Skip to content

Commit

Permalink
feat: login/logout support
Browse files Browse the repository at this point in the history
  • Loading branch information
dylandepass committed Feb 15, 2024
1 parent 96ea1c2 commit 2ad3293
Show file tree
Hide file tree
Showing 9 changed files with 350 additions and 31 deletions.
3 changes: 3 additions & 0 deletions src/extension/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -606,5 +606,8 @@
},
"error": {
"message": "Error"
},
"not_authorized": {
"message": "Not authorized"
}
}
39 changes: 34 additions & 5 deletions src/extension/app/components/action-bar/menu-item/menu-item.css.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@
import { css } from 'lit';

export const style = css`
:host(:not(.env-edit)[class]),
:host(:not(.env-edit)[class]) #label {
color: var(--spectrum-white);
}
:host(.current-env) #label {
font-weight: 700;
}
Expand Down Expand Up @@ -59,6 +54,40 @@ export const style = css`
right: 0;
}
:host(.user) {
border-bottom: 1px solid var(--spectrum-global-color-gray-300);
}
.user-item {
display: flex;
gap: 6px;
}
.user-item > slot {
display: flex;
padding-top: 3px;
}
.user-item .info {
display: flex;
flex-direction: column;
}
.user-item slot::slotted(img) {
width: 32px;
height: 32px;
}
.logout-item {
display: flex;
gap: 6px;
align-items: center;
}
.logout-item > slot::slotted(sp-icon-log-out) {
width: 32px;
}
@media (prefers-color-scheme: light) {
:host(.current-env) #label,
:host(.current-env) [name="description"]::slotted(*){
Expand Down
61 changes: 45 additions & 16 deletions src/extension/app/components/action-bar/menu-item/menu-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,54 @@ class MenuItem extends SPMenuItem {
];
}

render() {
return html`
<slot name="icon"></slot>
<div id="label">
<slot id="slot"></slot>
renderMenuItem() {
if (this.classList.contains('user')) {
return html`
<div class="user-item">
<slot name="icon"></slot>
<div class="info">
<div id="label">
<slot id="slot"></slot>
</div>
<slot name="description"></slot>
<slot name="value"></slot>
</div>
</div>
<slot name="description"></slot>
<slot name="value"></slot>
${this.href && this.href.length > 0
? super.renderAnchor({
id: 'button',
ariaHidden: true,
className: 'button anchor hidden',
})
: ''}
${this.getAttribute('update') ? html`<sp-status-light size="m" variant="notice"></sp-status-light>` : ''}
${this.renderSubmenu()}
`;
} else if (this.classList.contains('logout')) {
return html`
<div class="logout-item">
<slot name="icon"></slot>
<div id="label">
<slot id="slot"></slot>
</div>
<slot name="value"></slot>
</div>`;
}

return html`
<slot name="icon"></slot>
<slot name="avatar"></slot>
<div id="label">
<slot id="slot"></slot>
</div>
<slot name="description"></slot>
<slot name="value"></slot>
${this.href && this.href.length > 0
? super.renderAnchor({
id: 'button',
ariaHidden: true,
className: 'button anchor hidden',
})
: ''}
${this.getAttribute('update') ? html`<sp-status-light size="m" variant="notice"></sp-status-light>` : ''}
${this.renderSubmenu()}
`;
}

render() {
return this.renderMenuItem();
}
}

customElements.define('sp-menu-item', MenuItem);
42 changes: 36 additions & 6 deletions src/extension/app/components/plugin/env-switcher/env-switcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,38 @@ export class EnvironmentSwitcher extends MobxLitElement {
this.renderMenu();
}

/**
* Determines if the user is authorized for the specified environment
* @param {string} env - The environment to check
* @returns {boolean} - True if the user is authorized for the environment
*/
authorizedForEnv(env) {
const environment = appStore.status[env];
const status = environment?.status ?? null;

if (status === 403) {
return false;
}

return true;
}

/**
* Returns the last modified label for the specified environment
* @param {string} id - The id of the plugin
* @param {string} lastModified - The last modified date
* @returns {string} - The last modified label
*/
getLastModifiedLabel(id, lastModified) {
if (!this.authorizedForEnv(id)) {
return appStore.i18n('not_authorized');
}

return lastModified
? appStore.i18n(`${id}_last_updated`).replace('$1', getTimeAgo(appStore.languageDict, lastModified))
: appStore.i18n(`${id}_never_updated`);
}

/**
* Creates a menu item with specified attributes and a description.
*
Expand Down Expand Up @@ -130,9 +162,7 @@ export class EnvironmentSwitcher extends MobxLitElement {

const description = createTag({
tag: 'span',
text: lastModified
? appStore.i18n(`${id}_last_updated`).replace('$1', getTimeAgo(appStore.languageDict, lastModified))
: appStore.i18n(`${id}_never_updated`),
text: this.getLastModifiedLabel(id, lastModified),
attrs: {
slot: 'description',
},
Expand Down Expand Up @@ -195,8 +225,8 @@ export class EnvironmentSwitcher extends MobxLitElement {
}

// Check if preview is newer than live, if so add update flag
if ((!liveLastMod
|| (liveLastMod && new Date(liveLastMod) < new Date(previewLastMod)))) {
if (status.live?.status === 200
&& (!liveLastMod || (liveLastMod && new Date(liveLastMod) < new Date(previewLastMod)))) {
liveMenuItem.setAttribute('update', 'true');
}

Expand Down Expand Up @@ -282,6 +312,6 @@ export class EnvironmentSwitcher extends MobxLitElement {
}

render() {
return html`<action-bar-picker icons="none" @change=${this.onChange} .disabled=${!this.ready}></action-bar-picker>`;
return html`<action-bar-picker icons="none" @change=${this.onChange} .disabled=${!this.ready || appStore.authenticationRequired()}></action-bar-picker>`;
}
}
99 changes: 99 additions & 0 deletions src/extension/app/components/plugin/login/login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright 2023 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/

import { customElement } from 'lit/decorators.js';
import { reaction } from 'mobx';
import { html, LitElement, css } from 'lit';
import { appStore } from '../../../store/app.js';

/**
* Login Button component
* @element login-button
* @class LoginButton
*/
@customElement('login-button')
export class LoginButton extends LitElement {
static styles = css`
sp-action-menu {
--mod-popover-content-area-spacing-vertical: 0;
--mod-popover-animation-distance: 15px;
}
sp-action-menu sp-menu-item {
min-height: 56px;
padding-inline-start: 12px;
min-width: 240px;
}
sp-action-menu sp-menu-item .no-picture {
display: flex;
width: 32px;
height: 32px;
align-items: center;
justify-content: center;
}
`;

connectedCallback() {
super.connectedCallback();

reaction(
() => appStore.status,
() => {
this.requestUpdate();
},
);
}

login() {
appStore.login(true);
}

logout() {
appStore.logout();
}

renderLogin() {
const { profile } = appStore.status;
return html`
${!appStore.status.profile || !appStore.isAuthenticated()
? html`
<sp-action-button quiet class="login" @click=${this.login}>Sign in</sp-action-button>
` : ''
}
${appStore.isAuthenticated()
? html`
<sp-action-menu
selects="single"
placement="top"
quiet
>
<sp-icon-real-time-customer-profile slot="icon"></sp-icon-real-time-customer-profile>
<sp-menu-item class="user" value="user">
${profile.picture ? `<img src=${profile.picture} slot="icon" alt=${profile.name} />` : html`<div class="no-picture" slot="icon"><sp-icon-user size="xl"></sp-icon-user></div>`}
${profile.name}
<span slot="description">${profile.email}</span>
</sp-menu-item>
<sp-menu-item class="logout" value="logourt" @click=${this.logout}>
<sp-icon-log-out slot="icon" size="xl"></sp-icon-log-out>
Logout
</sp-menu-item>
</sp-action-menu>
` : ''
}
`;
}

render() {
return this.renderLogin();
}
}
6 changes: 2 additions & 4 deletions src/extension/app/components/plugin/plugin-action-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,13 @@ export class PluginActionBar extends MobxLitElement {
return appStore.initialized ? html`
<action-bar>
<sp-action-group>
<img class="logo" alt="adobe logo" src=${logo} />
<sp-divider size="s" vertical></sp-divider>
${this.renderPlugins()}
</sp-action-group>
<sp-divider size="s" vertical></sp-divider>
<sp-action-group>
<sp-action-button quiet aria-label="profile">
<sp-icon-real-time-customer-profile slot="icon"></sp-icon-real-time-customer-profile>
</sp-action-button>
<login-button></login-button>
<img class="logo" alt="adobe logo" src=${logo} />
</sp-action-group>
</action-bar>
` : '';
Expand Down
Loading

0 comments on commit 2ad3293

Please sign in to comment.