Skip to content

Commit

Permalink
GH-72 - Collaboration Awareness
Browse files Browse the repository at this point in the history
Show collab awareness status as icons just left of the publish button

If the user is known their initial is displayed.
If the user is not known a generic 'user' icon is displayed.

When hovering over the icon the full name is shown as a tooltip.

When collab is disconnected disable the editor until it reconnects.

Collab UX Polish

* Simplified integration between prose/index and da-title.
* prose/index only responsible for data, da-title is presentation.
* Turned user icon into clickable initial pill. Clicking shows full name popover.
* Cloud is also clickable for more detailed status
  • Loading branch information
bosschaert authored and auniverseaway committed Mar 7, 2024
1 parent ed99331 commit c380d0f
Show file tree
Hide file tree
Showing 12 changed files with 510 additions and 49 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/da-email-bot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Dark Alley release email

on:
pull_request_target:
types:
- closed
branches:
- main

jobs:
action:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Use email bot
uses: adobecom/da-email-bot@main
env:
SG_TO_EMAIL: ${{ secrets.SG_TO_EMAIL }}
SG_FROM_EMAIL: ${{ secrets.SG_FROM_EMAIL }}
SG_FROM_NAME: ${{ secrets.SG_FROM_NAME }}
SG_KEY: ${{ secrets.SG_KEY }}
SG_TEMPLATE: 'd-24723d9fc5964674a61426db17553c58'
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Lint
name: Lint and Test
on:
push:
branches:
Expand Down Expand Up @@ -29,3 +29,6 @@ jobs:
- name: Lint the code
run: npm run lint

# Commenting out running the tests until all existing test failures have been fixed
# - name: Run the tests
# run: npm t
5 changes: 5 additions & 0 deletions blocks/edit/da-library/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ function decorateImages(element, path) {
// eslint-disable-next-line no-unused-vars
const url = new URL(path);
element.querySelectorAll('img').forEach((img) => {
if (img.getAttribute('src').startsWith('./')) {
const srcSplit = img.src.split('/');
const mediaPath = srcSplit.pop();
img.src = `${url.origin}/${mediaPath}`;
}
const { width, height } = img;
const ratio = width > 200 ? 200 / width : 1;
img.width = width * ratio;
Expand Down
133 changes: 131 additions & 2 deletions blocks/edit/da-title/da-title.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
padding: 48px 0;
}

:host > svg {
display: none;
}

h1 {
margin-top: 0;
}
Expand Down Expand Up @@ -54,7 +58,7 @@ h1 {
opacity: 1;
}

.da-title-name-label:before {
.da-title-name-label::before {
display: block;
content: '';
position: absolute;
Expand All @@ -65,8 +69,80 @@ h1 {
background: url('/blocks/edit/img/left-large.svg') center/18px no-repeat;
}

.da-title-actions {
.da-title-collab-actions-wrapper {
display: flex;
margin-bottom: 0.67em;
}

.collab-status {
display: flex;
align-items: center;
justify-content: end;
}

.collab-icon {
position: relative;
font-size: 12px;
font-weight: 700;
}

.collab-icon:hover {
z-index: 2;
}

.collab-icon.collab-popup::after {
display: block;
content: attr(data-popup-content);
position: absolute;
bottom: -32px;
left: 50%;
transform: translateX(-50%);
text-align: center;
text-transform: capitalize;
background: #676767;
color: #FFF;
white-space: nowrap;
padding: 0 8px;
border-radius: 4px;
}

.collab-icon-user {
height: 24px;
border-radius: 12px;
background: rgb(171 171 171 / 50%);
display: flex;
align-items: center;
justify-content: center;
text-transform: uppercase;
color: #676767;
margin-right: -6px;
padding: 0 12px;
user-select: none;
-webkit-user-select: none;
}

.collab-icon-user:hover {
background: rgb(150 150 150 / 50%);
}

.collab-status-cloud {
height: 27px;
margin-left: -4px;
margin-bottom: -3px;
color: rgb(20 115 230 / 80%);
}

.collab-icon.collab-status-cloud.collab-popup::after {
bottom: -29px;
}

.collab-status-cloud svg {
pointer-events: none;
width: 37.5px;
height: 27px;
}

.da-title-actions {
right: -12px;
position: relative;
border: 12px solid transparent;
Expand Down Expand Up @@ -120,3 +196,56 @@ h1 {
bottom: 22px;
}
}

/* -------------------------------------
Styles for the collab awarness widget
------------------------------------- */

div.collab-awareness {
flex: 1;
display: flex;
align-self: center;
justify-content: flex-end;
padding-right: 16px;
}

div.collab-other-users {
display: flex;
flex-direction: row-reverse;
}

div.collab-other-users div {
display: flex;
}

img.collab-icon {
width: 19px;
height: 19px;
}


div.collab-users {
display: flex;
flex-direction: row-reverse;
}

div.collab-initial {
background-color: var(--color-accent);
border-color: var(--color-accent);
border-style: solid;
border-width: 1px;
border-radius: 50%;
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
margin-top: 0.5px;
}

div.collab-initial p {
color: white;
font-size: 14px;
font-weight: 700;
margin-bottom: 15px;
}
89 changes: 69 additions & 20 deletions blocks/edit/da-title/da-title.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
import { LitElement, html } from '../../../deps/lit/lit-core.min.js';
import { LitElement, html, nothing } from '../../../deps/lit/lit-core.min.js';
import { saveToDa, saveToAem } from '../utils/helpers.js';
import inlinesvg from '../../shared/inlinesvg.js';
import getSheet from '../../shared/sheet.js';

const sheet = await getSheet('/blocks/edit/da-title/da-title.css');

const ICONS = [
'/blocks/edit/img/Smock_Cloud_18_N.svg',
'/blocks/edit/img/Smock_CloudDisconnected_18_N.svg',
'/blocks/edit/img/Smock_CloudError_18_N.svg',
];

const CLOUD_ICONS = {
connected: 'spectrum-Cloud-connected',
offline: 'spectrum-Cloud-offline',
connecting: 'spectrum-Cloud-error',
error: 'spectrum-Cloud-error',
};

export default class DaTitle extends LitElement {
static properties = {
details: { attribute: false },
collabStatus: { attribute: false },
collabUsers: { attribute: false },
_actionsVis: {},
};

connectedCallback() {
super.connectedCallback();
this.shadowRoot.adoptedStyleSheets = [sheet];
this._actionsVis = false;
inlinesvg({ parent: this.shadowRoot, paths: ICONS });
}

async handleAction(action) {
Expand Down Expand Up @@ -48,6 +65,35 @@ export default class DaTitle extends LitElement {
this._actionsVis = !this._actionsVis;
}

popover({ target }) {
// If toggling off, simply remove;
if (target.classList.contains('collab-popup')) {
target.classList.remove('collab-popup');
return;
}
// Find all open popups and close them
const openPopups = this.shadowRoot.querySelectorAll('.collab-popup');
openPopups.forEach((pop) => { pop.classList.remove('collab-popup'); });
target.classList.add('collab-popup');
}

renderCollabUsers() {
return html`${this.collabUsers.map((user) => {
const initials = user.split(' ').map((name) => name.toString().substring(0, 1));
return html`<div class="collab-icon collab-icon-user" data-popup-content="${user}" @click=${this.popover}>${initials.join('')}</div>`;
})}`;
}

renderCollab() {
return html`
<div class="collab-status">
${this.collabUsers ? this.renderCollabUsers() : nothing}
<div class="collab-icon collab-status-cloud collab-status-${this.collabStatus}" data-popup-content="${this.collabStatus}" @click=${this.popover}>
<svg class="icon"><use href="#${CLOUD_ICONS[this.collabStatus]}"/></svg>
</div>
</div>`;
}

render() {
return html`
<div class="da-title-inner">
Expand All @@ -58,25 +104,28 @@ export default class DaTitle extends LitElement {
class="da-title-name-label">${this.details.parentName}</a>
<h1>${this.details.name}</h1>
</div>
<div class="da-title-actions${this._actionsVis ? ' is-open' : ''}">
<button
@click=${this.handlePreview}
class="con-button blue da-title-action"
aria-label="Send">
Preview
</button>
<button
@click=${this.handlePublish}
class="con-button blue da-title-action"
aria-label="Send">
Publish
</button>
<button
@click=${this.toggleActions}
class="con-button blue da-title-action-send"
aria-label="Send">
<span class="da-title-action-send-icon"></span>
</button>
<div class="da-title-collab-actions-wrapper">
${this.collabStatus ? this.renderCollab() : nothing}
<div class="da-title-actions${this._actionsVis ? ' is-open' : ''}">
<button
@click=${this.handlePreview}
class="con-button blue da-title-action"
aria-label="Send">
Preview
</button>
<button
@click=${this.handlePublish}
class="con-button blue da-title-action"
aria-label="Send">
Publish
</button>
<button
@click=${this.toggleActions}
class="con-button blue da-title-action-send"
aria-label="Send">
<span class="da-title-action-send-icon"></span>
</button>
</div>
</div>
</div>
`;
Expand Down
7 changes: 7 additions & 0 deletions blocks/edit/img/Smock_CloudDisconnected_18_N.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions blocks/edit/img/Smock_CloudError_18_N.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions blocks/edit/img/Smock_Cloud_18_N.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit c380d0f

Please sign in to comment.