mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Adds new view as banner
Summary: Diff removes view-as pill in the document breadcrumbs and add new view-as banner. Note: Banners are still missing mechanism to handle several banners. As of now both doc-usage and view-as banners could show up at the same time. Test Plan: Refactored existing test. Reviewers: jarek Reviewed By: jarek Subscribers: jarek Differential Revision: https://phab.getgrist.com/D3732
This commit is contained in:
@@ -16,7 +16,7 @@ export interface BannerOptions {
|
||||
* Warning banners have a yellow background. Error banners have a red
|
||||
* background.
|
||||
*/
|
||||
style: 'warning' | 'error';
|
||||
style: 'warning' | 'error' | 'info';
|
||||
|
||||
/**
|
||||
* Optional variant of `content` to display when screen width becomes narrow.
|
||||
@@ -40,6 +40,11 @@ export interface BannerOptions {
|
||||
*/
|
||||
showExpandButton?: boolean;
|
||||
|
||||
/**
|
||||
* If provided, applies the css class to the banner container.
|
||||
*/
|
||||
bannerCssClass?: string;
|
||||
|
||||
/**
|
||||
* Function that is called when the banner close button is clicked.
|
||||
*
|
||||
@@ -59,7 +64,7 @@ export class Banner extends Disposable {
|
||||
}
|
||||
|
||||
public buildDom() {
|
||||
return cssBanner(
|
||||
return cssBanner({class: this._options.bannerCssClass || ''},
|
||||
cssBanner.cls(`-${this._options.style}`),
|
||||
this._buildContent(),
|
||||
this._buildButtons(),
|
||||
@@ -114,6 +119,11 @@ const cssBanner = styled('div', `
|
||||
gap: 16px;
|
||||
color: white;
|
||||
|
||||
&-info {
|
||||
color: black;
|
||||
background: #FFFACD;
|
||||
}
|
||||
|
||||
&-warning {
|
||||
background: #E6A117;
|
||||
}
|
||||
|
||||
132
app/client/components/ViewAsBanner.ts
Normal file
132
app/client/components/ViewAsBanner.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
import { reportError } from 'app/client/models/AppModel';
|
||||
import { Banner } from "app/client/components/Banner";
|
||||
import { DocPageModel } from "app/client/models/DocPageModel";
|
||||
import { icon } from "app/client/ui2018/icons";
|
||||
import { primaryButtonLink } from 'app/client/ui2018/buttons';
|
||||
import { Disposable, dom, styled } from "grainjs";
|
||||
import { testId, theme } from 'app/client/ui2018/cssVars';
|
||||
import { urlState } from 'app/client/models/gristUrlState';
|
||||
import { userOverrideParams } from 'app/common/gristUrls';
|
||||
import { cssMenuItem } from 'popweasel';
|
||||
import { getUserRoleText } from 'app/common/UserAPI';
|
||||
import { PermissionDataWithExtraUsers } from 'app/common/ActiveDocAPI';
|
||||
import { waitGrainObs } from 'app/common/gutil';
|
||||
import { cssSelectBtn } from 'app/client/ui2018/select';
|
||||
import { ACLUsersPopup } from 'app/client/aclui/ACLUsers';
|
||||
import { UserOverride } from 'app/common/DocListAPI';
|
||||
import { makeT } from 'app/client/lib/localization';
|
||||
|
||||
const t = makeT('components.ViewAsBanner');
|
||||
|
||||
export class ViewAsBanner extends Disposable {
|
||||
|
||||
private _userOverride = this._docPageModel.userOverride;
|
||||
private _usersPopup = ACLUsersPopup.create(this);
|
||||
|
||||
constructor (private _docPageModel: DocPageModel) {
|
||||
super();
|
||||
}
|
||||
|
||||
public buildDom() {
|
||||
return dom.maybe(this._userOverride, (userOverride) => {
|
||||
this._initViewAsUsers().catch(reportError);
|
||||
return dom.create(Banner, {
|
||||
content: this._buildContent(userOverride),
|
||||
style: 'info',
|
||||
showCloseButton: false,
|
||||
showExpandButton: false,
|
||||
bannerCssClass: cssBanner.className,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private _buildContent(userOverride: UserOverride) {
|
||||
const {user, access} = userOverride;
|
||||
return cssContent(
|
||||
cssMessageText(
|
||||
cssMessageIcon('EyeShow'),
|
||||
'You are viewing this document as',
|
||||
),
|
||||
cssSelectBtn(
|
||||
{tabIndex: '0'},
|
||||
cssBtnText(
|
||||
user ? cssMember(
|
||||
user.name || user.email,
|
||||
cssRole('(', getUserRoleText({...user, access}), ')', dom.show(Boolean(access))),
|
||||
) : t('UnknownUser'),
|
||||
),
|
||||
dom(
|
||||
'div', {style: 'flex: none;'},
|
||||
cssInlineCollapseIcon('Collapse'),
|
||||
),
|
||||
elem => this._usersPopup.attachPopup(elem, {}),
|
||||
testId('select-open'),
|
||||
),
|
||||
cssPrimaryButtonLink(
|
||||
'View as Yourself', cssIcon('Convert'),
|
||||
urlState().setHref(userOverrideParams(null)),
|
||||
testId('revert'),
|
||||
),
|
||||
testId('view-as-banner'),
|
||||
);
|
||||
}
|
||||
|
||||
private async _initViewAsUsers() {
|
||||
await waitGrainObs(this._docPageModel.gristDoc);
|
||||
const permissionData = await this._getUsersForViewAs();
|
||||
this._usersPopup.init(this._docPageModel, permissionData);
|
||||
}
|
||||
|
||||
private _getUsersForViewAs(): Promise<PermissionDataWithExtraUsers> {
|
||||
const docId = this._docPageModel.currentDocId.get()!;
|
||||
const docApi = this._docPageModel.appModel.api.getDocAPI(docId);
|
||||
return docApi.getUsersForViewAs();
|
||||
}
|
||||
}
|
||||
|
||||
const cssContent = styled('div', `
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
column-gap: 13px;
|
||||
align-items: center;
|
||||
& .${cssSelectBtn.className} {
|
||||
width: 184px;
|
||||
}
|
||||
`);
|
||||
const cssIcon = styled(icon, `
|
||||
margin-left: 10px;
|
||||
`);
|
||||
const cssMember = styled('span', `
|
||||
font-weight: 500;
|
||||
color: ${theme.text};
|
||||
|
||||
.${cssMenuItem.className}-sel & {
|
||||
color: ${theme.menuItemSelectedFg};
|
||||
}
|
||||
`);
|
||||
const cssRole = styled('span', `
|
||||
font-weight: 400;
|
||||
margin-left: 1ch;
|
||||
`);
|
||||
const cssMessageText = styled('span', `
|
||||
`);
|
||||
const cssMessageIcon = styled(icon, `
|
||||
margin-right: 10px;
|
||||
`);
|
||||
const cssPrimaryButtonLink = styled(primaryButtonLink, `
|
||||
margin-left: 5px;
|
||||
`);
|
||||
const cssBtnText = styled('div', `
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
`);
|
||||
const cssInlineCollapseIcon = styled(icon, `
|
||||
margin: 0 2px;
|
||||
pointer-events: none;
|
||||
`);
|
||||
const cssBanner = styled('div', `
|
||||
border-bottom: 1px solid ${theme.pagePanelsBorder};
|
||||
height: 45px;
|
||||
`);
|
||||
Reference in New Issue
Block a user