Add support for items list as notes are "liked"
This commit is contained in:
Родитель
debbb697d8
Коммит
c1a4789d11
|
@ -10,6 +10,7 @@
|
|||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fluentui/react": "^8.29.2",
|
||||
"@fluentui/react-icons-mdl2": "^1.2.1",
|
||||
"@fluidframework/azure-client": "^0.46.0",
|
||||
"@fluidframework/test-runtime-utils": "0.46.0",
|
||||
"@microsoft/mgt-element": "^2.2.1",
|
||||
|
@ -2226,6 +2227,37 @@
|
|||
"react": ">=16.8.0 <18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@fluentui/react-icon-provider": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@fluentui/react-icon-provider/-/react-icon-provider-1.2.1.tgz",
|
||||
"integrity": "sha512-P6Agy31ZF/S+4xDNBJzLQejkncKvblvhSwl0er4sLgPqID2fcIT6y0MGS4kOqMib9sC+aejpIav2pHqd+EMChg==",
|
||||
"dependencies": {
|
||||
"@fluentui/set-version": "^8.1.4",
|
||||
"@fluentui/style-utilities": "^8.3.1",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": ">=16.8.0 <18.0.0",
|
||||
"@types/react-dom": ">=16.8.0 <18.0.0",
|
||||
"react": ">=16.8.0 <18.0.0",
|
||||
"react-dom": ">=16.8.0 <18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@fluentui/react-icons-mdl2": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@fluentui/react-icons-mdl2/-/react-icons-mdl2-1.2.1.tgz",
|
||||
"integrity": "sha512-vQRrgeDfmDxZJCeh/iW8yCAtpwfUrpHI0QU2NojXl5U0uv4KuOHp39UJvu8dzdp1zZ7arEYMoIgcq0eNqssnQA==",
|
||||
"dependencies": {
|
||||
"@fluentui/react-icon-provider": "^1.2.1",
|
||||
"@fluentui/set-version": "^8.1.4",
|
||||
"@fluentui/utilities": "^8.3.1",
|
||||
"@microsoft/load-themed-styles": "^1.10.26",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0 <18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@fluentui/react-window-provider": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@fluentui/react-window-provider/-/react-window-provider-2.1.4.tgz",
|
||||
|
@ -28073,6 +28105,28 @@
|
|||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"@fluentui/react-icon-provider": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@fluentui/react-icon-provider/-/react-icon-provider-1.2.1.tgz",
|
||||
"integrity": "sha512-P6Agy31ZF/S+4xDNBJzLQejkncKvblvhSwl0er4sLgPqID2fcIT6y0MGS4kOqMib9sC+aejpIav2pHqd+EMChg==",
|
||||
"requires": {
|
||||
"@fluentui/set-version": "^8.1.4",
|
||||
"@fluentui/style-utilities": "^8.3.1",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"@fluentui/react-icons-mdl2": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@fluentui/react-icons-mdl2/-/react-icons-mdl2-1.2.1.tgz",
|
||||
"integrity": "sha512-vQRrgeDfmDxZJCeh/iW8yCAtpwfUrpHI0QU2NojXl5U0uv4KuOHp39UJvu8dzdp1zZ7arEYMoIgcq0eNqssnQA==",
|
||||
"requires": {
|
||||
"@fluentui/react-icon-provider": "^1.2.1",
|
||||
"@fluentui/set-version": "^8.1.4",
|
||||
"@fluentui/utilities": "^8.3.1",
|
||||
"@microsoft/load-themed-styles": "^1.10.26",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"@fluentui/react-window-provider": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@fluentui/react-window-provider/-/react-window-provider-2.1.4.tgz",
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@fluentui/react": "^8.29.2",
|
||||
"@fluentui/react-icons-mdl2": "^1.2.1",
|
||||
"fluid-framework": "^0.46.0",
|
||||
"@fluidframework/azure-client": "^0.46.0",
|
||||
"@fluidframework/test-runtime-utils": "0.46.0",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { FluidContainer, ISharedMap, SharedMap } from "fluid-framework";
|
||||
import { AzureMember } from "@fluidframework/azure-client";
|
||||
import { NoteData, Position } from "./Types";
|
||||
import { LikedNote, NoteData, Position } from "./Types";
|
||||
|
||||
const c_NoteIdPrefix = "noteId_";
|
||||
const c_PositionPrefix = "position_";
|
||||
|
@ -19,6 +19,7 @@ export type BrainstormModel = Readonly<{
|
|||
GetNoteLikedUsers(noteId: string): AzureMember[];
|
||||
DeleteNote(noteId: string): void;
|
||||
NoteIds: string[];
|
||||
LikedNotes: LikedNote[];
|
||||
setChangeListener(listener: () => void): void;
|
||||
removeChangeListener(listener: () => void): void;
|
||||
}>;
|
||||
|
@ -49,6 +50,12 @@ export function createBrainstormModel(fluid: FluidContainer): BrainstormModel {
|
|||
sharedMap.set(c_ColorPrefix + noteId, noteColor);
|
||||
};
|
||||
|
||||
const numLikesCalculated = (noteId: string) => {
|
||||
return Array.from(sharedMap
|
||||
.keys())
|
||||
.filter((key: string) => key.includes(c_votePrefix + noteId))
|
||||
.filter((key: string) => sharedMap.get(key) !== undefined).length;
|
||||
};
|
||||
|
||||
return {
|
||||
CreateNote(noteId: string, myAuthor: AzureMember): NoteData {
|
||||
|
@ -57,10 +64,7 @@ export function createBrainstormModel(fluid: FluidContainer): BrainstormModel {
|
|||
text: sharedMap.get(c_TextPrefix + noteId),
|
||||
position: sharedMap.get(c_PositionPrefix + noteId)!,
|
||||
author: sharedMap.get(c_AuthorPrefix + noteId)!,
|
||||
numLikesCalculated: Array.from(sharedMap
|
||||
.keys())
|
||||
.filter((key: string) => key.includes(c_votePrefix + noteId))
|
||||
.filter((key: string) => sharedMap.get(key) !== undefined).length,
|
||||
numLikesCalculated: numLikesCalculated(noteId),
|
||||
didILikeThisCalculated:
|
||||
Array.from(sharedMap
|
||||
.keys())
|
||||
|
@ -127,6 +131,38 @@ export function createBrainstormModel(fluid: FluidContainer): BrainstormModel {
|
|||
);
|
||||
},
|
||||
|
||||
get LikedNotes(): LikedNote[] {
|
||||
return (
|
||||
Array.from(sharedMap
|
||||
.keys())
|
||||
// Only look at keys which represent if a note exists or not
|
||||
.filter((key: String) => key.includes(c_NoteIdPrefix))
|
||||
// Modify the note ids to not expose the prefix
|
||||
.map((noteIdWithPrefix) =>
|
||||
noteIdWithPrefix.substring(c_NoteIdPrefix.length)
|
||||
)
|
||||
// Remove notes which are incomplete or deleted
|
||||
.filter((noteId) =>
|
||||
!IsDeletedNote(noteId) && numLikesCalculated(noteId) > 0 &&
|
||||
sharedMap.get(c_TextPrefix + noteId)
|
||||
)
|
||||
.map((noteId) => {
|
||||
const text = sharedMap.get(c_TextPrefix + noteId);
|
||||
const color = sharedMap.get(c_ColorPrefix + noteId);
|
||||
const author = sharedMap.get(c_AuthorPrefix + noteId);
|
||||
return {
|
||||
text,
|
||||
color,
|
||||
author,
|
||||
numLikesCalculated: numLikesCalculated(noteId)
|
||||
};
|
||||
})
|
||||
.sort((a: LikedNote, b: LikedNote) => {
|
||||
return b.numLikesCalculated - a.numLikesCalculated;
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
setChangeListener(listener: () => void): void {
|
||||
sharedMap.on("valueChanged", listener);
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { AzureConnectionConfig, InsecureTokenProvider } from "@fluidframework/azure-client";
|
||||
import { SharedMap } from "fluid-framework";
|
||||
import { generateUser } from './utils';
|
||||
import { generateUser } from './Utils';
|
||||
|
||||
export const useAzureFrs = process.env.REACT_APP_FLUID_CLIENT === "frs";
|
||||
export const user = generateUser();
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
export function Navbar() {
|
||||
return (
|
||||
<header>
|
||||
<div className="container">
|
||||
<div className="title">Let's Brainstorm</div>
|
||||
<div className="login"></div>
|
||||
<div className="grid-container">
|
||||
<div className="left title">Let's Brainstorm</div>
|
||||
<div className="right login end"></div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
|
|
|
@ -19,3 +19,10 @@ export type ColorId =
|
|||
| "Pink"
|
||||
| "Purple"
|
||||
| "Orange";
|
||||
|
||||
export type LikedNote = {
|
||||
text: string,
|
||||
color: string,
|
||||
author: AzureMember,
|
||||
numLikesCalculated: number
|
||||
};
|
||||
|
|
|
@ -4,17 +4,16 @@
|
|||
*/
|
||||
|
||||
import { initializeIcons, ThemeProvider } from "@fluentui/react";
|
||||
import { AzureClient, AzureResources } from '@fluidframework/azure-client';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { BrainstormView } from './view/BrainstormView';
|
||||
import "./view/index.css";
|
||||
import "./view/App.css";
|
||||
import { themeNameToTheme } from './view/Themes';
|
||||
import { connectionConfig, containerSchema } from "./Config";
|
||||
import { Navbar } from './Navbar';
|
||||
import { Providers } from '@microsoft/mgt-element';
|
||||
import { Msal2Provider } from '@microsoft/mgt-msal2-provider';
|
||||
import { getFluidContainer } from "./Utils";
|
||||
|
||||
Providers.globalProvider = new Msal2Provider({
|
||||
clientId: '26fa7fdf-ae13-4db0-84f8-8249376812dc'
|
||||
|
@ -23,37 +22,7 @@ Providers.globalProvider = new Msal2Provider({
|
|||
export async function start() {
|
||||
initializeIcons();
|
||||
|
||||
async function createOrGetContainer() :
|
||||
Promise<{ containerId: string, azureResources: AzureResources}> {
|
||||
let containerId = '';
|
||||
// Check if there's a previous containerId (user may have simply logged out)
|
||||
const prevContainerId = sessionStorage.getItem("containerId");
|
||||
if (location.hash.length === 0) {
|
||||
if (prevContainerId) {
|
||||
location.hash = prevContainerId;
|
||||
containerId = prevContainerId;
|
||||
}
|
||||
}
|
||||
else {
|
||||
containerId = location.hash.substring(1);
|
||||
}
|
||||
|
||||
const client = new AzureClient(connectionConfig);
|
||||
let azureResources: AzureResources;
|
||||
if (containerId) {
|
||||
azureResources = await client.getContainer(containerId, containerSchema);
|
||||
}
|
||||
else {
|
||||
azureResources = await client.createContainer(containerSchema);
|
||||
// Temporary until attach() is available (per Fluid engineering)
|
||||
containerId = azureResources.fluidContainer.id;
|
||||
location.hash = containerId;
|
||||
}
|
||||
sessionStorage.setItem("containerId", containerId);
|
||||
return {containerId, azureResources};
|
||||
}
|
||||
|
||||
let {azureResources} = await createOrGetContainer();
|
||||
let {azureResources} = await getFluidContainer();
|
||||
|
||||
if (!azureResources.fluidContainer.connected) {
|
||||
await new Promise<void>((resolve) => {
|
||||
|
|
33
src/utils.ts
33
src/utils.ts
|
@ -1,3 +1,36 @@
|
|||
import { AzureClient, AzureResources } from "@fluidframework/azure-client";
|
||||
import { connectionConfig, containerSchema } from "./Config";
|
||||
|
||||
export async function getFluidContainer() :
|
||||
Promise<{ containerId: string, azureResources: AzureResources}> {
|
||||
let containerId = '';
|
||||
// Check if there's a previous containerId (user may have simply logged out)
|
||||
const prevContainerId = sessionStorage.getItem("containerId");
|
||||
if (location.hash.length === 0) {
|
||||
if (prevContainerId) {
|
||||
location.hash = prevContainerId;
|
||||
containerId = prevContainerId;
|
||||
}
|
||||
}
|
||||
else {
|
||||
containerId = location.hash.substring(1);
|
||||
}
|
||||
|
||||
const client = new AzureClient(connectionConfig);
|
||||
let azureResources: AzureResources;
|
||||
if (containerId) {
|
||||
azureResources = await client.getContainer(containerId, containerSchema);
|
||||
}
|
||||
else {
|
||||
azureResources = await client.createContainer(containerSchema);
|
||||
// Temporary until attach() is available (per Fluid engineering)
|
||||
containerId = azureResources.fluidContainer.id;
|
||||
location.hash = containerId;
|
||||
}
|
||||
sessionStorage.setItem("containerId", containerId);
|
||||
return {containerId, azureResources};
|
||||
}
|
||||
|
||||
export function generateUser() {
|
||||
const randomUser = {
|
||||
id: uuidv4(),
|
||||
|
|
|
@ -28,24 +28,96 @@ header {
|
|||
height: 40px;
|
||||
}
|
||||
|
||||
.container {
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-column-gap: 0px;
|
||||
grid-template-areas: "title login";
|
||||
grid-template-areas: "left right";
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
color: white;
|
||||
margin-left: 25px;
|
||||
margin-right: 25px;
|
||||
}
|
||||
|
||||
.left {
|
||||
grid-area: left;
|
||||
}
|
||||
|
||||
.right {
|
||||
grid-area: right;
|
||||
}
|
||||
|
||||
.end {
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.start {
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.title {
|
||||
grid-area: title;
|
||||
margin-left: 25px;
|
||||
font-size: 20px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.login {
|
||||
grid-area: login;
|
||||
justify-self: end;
|
||||
color: white;
|
||||
margin-right: 25px;
|
||||
}
|
||||
|
||||
.white {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.mr-15 {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.mb-5 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.selected-items {
|
||||
background-color: #efefef;
|
||||
}
|
||||
|
||||
.selected-items h2 {
|
||||
height: 15px;
|
||||
background-color: #ccc;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.selected-items h2 div {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.items-list ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 5px 0px 0px 10px;
|
||||
font-size: 12px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.items-list li {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.icon-wrapper {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
height: 20px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.circle-icon {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.circle-icon-overlay {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: #fff;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import { DndProvider } from 'react-dnd'
|
|||
import { HTML5Backend } from 'react-dnd-html5-backend'
|
||||
import { BrainstormModel, createBrainstormModel } from "../BrainstormModel";
|
||||
import { Header } from "./Header";
|
||||
import { ItemsList } from "./ItemsList";
|
||||
import { NoteSpace } from "./NoteSpace";
|
||||
|
||||
export const BrainstormView = (props: { frsResources: AzureResources }) => {
|
||||
|
@ -47,12 +48,17 @@ export const BrainstormView = (props: { frsResources: AzureResources }) => {
|
|||
author={authorInfo}
|
||||
members={members}
|
||||
/>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<NoteSpace
|
||||
model={model}
|
||||
author={authorInfo}
|
||||
/>
|
||||
</DndProvider>
|
||||
<div className="items-list">
|
||||
<ItemsList model={model} />
|
||||
</div>
|
||||
<div>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<NoteSpace
|
||||
model={model}
|
||||
author={authorInfo}
|
||||
/>
|
||||
</DndProvider>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ import { DefaultColor } from "./Color";
|
|||
import { ColorPicker } from "./ColorPicker";
|
||||
import { NoteData } from "../Types";
|
||||
import { NOTE_SIZE } from "./Note.style";
|
||||
import { uuidv4 } from '../utils';
|
||||
import { uuidv4 } from '../Utils';
|
||||
|
||||
export interface HeaderProps {
|
||||
model: BrainstormModel;
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { BrainstormModel } from "../BrainstormModel";
|
||||
import { ColorId, LikedNote } from "../Types";
|
||||
import { CircleFillIcon } from '@fluentui/react-icons-mdl2';
|
||||
import { ColorOptions } from "./Color";
|
||||
|
||||
export type ItemsListProps = Readonly<{
|
||||
model: BrainstormModel;
|
||||
}>;
|
||||
|
||||
export function ItemsList(props: ItemsListProps) {
|
||||
const { model } = props;
|
||||
const [notes, setNotes] = useState<readonly LikedNote[]>([]);
|
||||
// This runs when via model changes whether initiated by user or from external
|
||||
useEffect(() => {
|
||||
const syncLocalAndFluidState = () => {
|
||||
const likedNotes: LikedNote[] = model.LikedNotes;
|
||||
setNotes(likedNotes);
|
||||
};
|
||||
|
||||
syncLocalAndFluidState();
|
||||
model.setChangeListener(syncLocalAndFluidState);
|
||||
return () => model.removeChangeListener(syncLocalAndFluidState);
|
||||
}, [model]);
|
||||
|
||||
|
||||
return (
|
||||
<div className="items-list">
|
||||
|
||||
<div className="selected-items">
|
||||
<h2 className="grid-container">
|
||||
<div className="left">Selected Items</div>
|
||||
<div className="right end mr-15">Votes</div>
|
||||
</h2>
|
||||
{!!notes.length &&
|
||||
<ul>
|
||||
{notes.map((note, i) => {
|
||||
const iconColor = ColorOptions[note.color as ColorId].base;
|
||||
return (
|
||||
<li key={i}>
|
||||
<div className="grid-container">
|
||||
<div className="left">{note.text}</div>
|
||||
<div className="right end mr-15">
|
||||
<div className="icon-wrapper">
|
||||
<CircleFillIcon className="circle-icon"
|
||||
style={{color: iconColor}} />
|
||||
<span className="circle-icon-overlay">{note.numLikesCalculated}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -3,8 +3,8 @@ import { ColorOptions } from "./Color";
|
|||
import { ColorId } from "../Types";
|
||||
|
||||
export const NOTE_SIZE = {
|
||||
width: 300,
|
||||
height: 100
|
||||
width: 250,
|
||||
height: 75
|
||||
}
|
||||
|
||||
export const tooltipHostStyle: Partial<ITooltipHostStyles> = {
|
||||
|
@ -38,7 +38,13 @@ export const likesButtonStyle: IButtonStyles = {
|
|||
root: { backgroundColor: "transparent" },
|
||||
rootHovered: { backgroundColor: "transparent", fontSize: "18px" },
|
||||
rootPressed: { backgroundColor: "transparent" },
|
||||
iconHovered: { fontSize: "18px" }
|
||||
iconHovered: { fontSize: "18px" },
|
||||
};
|
||||
|
||||
export const likesButtonAuthorStyle: IButtonStyles = {
|
||||
root: { backgroundColor: "transparent" },
|
||||
rootHovered: { backgroundColor: "transparent", fontSize: "14px" },
|
||||
rootPressed: { backgroundColor: "transparent" },
|
||||
};
|
||||
|
||||
export function getRootStyleForColor(color: ColorId): IStyle {
|
||||
|
@ -49,7 +55,7 @@ export function getRootStyleForColor(color: ColorId): IStyle {
|
|||
boxShadow:
|
||||
"rgb(0 0 0 / 13%) 0px 1.6px 3.6px 0px, rgb(0 0 0 / 11%) 0px 0.3px 0.9px 0px",
|
||||
width: NOTE_SIZE.width,
|
||||
minHeight: NOTE_SIZE.height
|
||||
minHeight: NOTE_SIZE.height,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import { NoteBody } from "./NoteBody";
|
|||
|
||||
export type NoteProps = Readonly<{
|
||||
id: string;
|
||||
user: AzureMember;
|
||||
setPosition: (position: Position) => void;
|
||||
onLike: () => void;
|
||||
getLikedUsers: () => AzureMember[];
|
||||
|
|
|
@ -17,12 +17,14 @@ import {
|
|||
colorButtonStyle,
|
||||
likesButtonStyle,
|
||||
tooltipHostStyle,
|
||||
likesButtonAuthorStyle,
|
||||
} from "./Note.style";
|
||||
import { ReactionListCallout } from "./ReactionListCallout";
|
||||
import { NoteProps } from "./Note"
|
||||
|
||||
const HeaderComponent = (props: NoteProps) => {
|
||||
const colorButtonRef = React.useRef();
|
||||
const { user } = props;
|
||||
|
||||
const headerProps = {
|
||||
className: mergeStyles(getHeaderStyleForColor(props.color)),
|
||||
|
@ -84,7 +86,7 @@ const HeaderComponent = (props: NoteProps) => {
|
|||
iconProps: {
|
||||
iconName: props.didILikeThisCalculated ? "LikeSolid" : "Like",
|
||||
},
|
||||
buttonStyles: likesButtonStyle,
|
||||
buttonStyles: isAuthorNote() ? likesButtonAuthorStyle : likesButtonStyle,
|
||||
commandBarButtonAs: (props) => {
|
||||
return (
|
||||
<TooltipHost
|
||||
|
@ -123,9 +125,13 @@ const HeaderComponent = (props: NoteProps) => {
|
|||
title: "Delete Note",
|
||||
onClick: props.onDelete,
|
||||
buttonStyles: deleteButtonStyle,
|
||||
},
|
||||
}
|
||||
];
|
||||
|
||||
function isAuthorNote() {
|
||||
return user.userId && props.author.userId === user.userId;
|
||||
}
|
||||
|
||||
const nonResizingGroup = (props: IResizeGroupProps) => (
|
||||
<div>
|
||||
<div style={{ position: "relative" }}>
|
||||
|
|
|
@ -92,6 +92,7 @@ export function NoteSpace(props: NoteSpaceProps) {
|
|||
id={note.id}
|
||||
key={note.id}
|
||||
text={note.text}
|
||||
user={props.author}
|
||||
setPosition={setPosition}
|
||||
onLike={onLike}
|
||||
getLikedUsers={getLikedUsers}
|
||||
|
|
Загрузка…
Ссылка в новой задаче