Skip to content

Commit

Permalink
Alex krasn/relocate share button (microsoft#464)
Browse files Browse the repository at this point in the history
* feat: relocate share priject button to title bar

* strings
  • Loading branch information
alex-krasn authored Jul 31, 2020
1 parent 0e1b637 commit 78996ea
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 49 deletions.
5 changes: 5 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { Sidebar } from "./react/components/shell/sidebar";
import { StatusBar } from "./react/components/shell/statusBar";
import { StatusBarMetrics } from "./react/components/shell/statusBarMetrics";
import { TitleBar } from "./react/components/shell/titleBar";
import ShareProjectButton from "./react/components/shell/shareProjectButton";

import { getAppInsights } from './services/telemetryService';
import TelemetryProvider from "./providers/telemetry/telemetryProvider";
import "./App.scss";
Expand Down Expand Up @@ -79,6 +81,9 @@ export default class App extends React.Component<IAppProps> {
<TelemetryProvider after={() => { this.appInsights = getAppInsights() }}>
<div className={`app-shell platform-${platform}`}>
<TitleBar icon="TagGroup">
<div className="app-share-menu-icon">
<ShareProjectButton />
</div>
<div className="app-shortcuts-menu-icon">
<KeyboardShortcuts />
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/common/localization/en-us.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,6 @@ export const english: IAppStrings = {
}
},
farItems: {
share: "Share Project",
zoom: {
zoomOut: "Zoom out",
zoomIn: "Zoom in",
Expand Down Expand Up @@ -633,6 +632,7 @@ export const english: IAppStrings = {
}
},
shareProject: {
name: "Share Project",
errors: {
cannotDecodeString: "Cannot decode shared string! Please, check if your string has been modified.",
connectionNotFound: "Connection not found. Add shared project's connection to your connections.",
Expand Down
2 changes: 1 addition & 1 deletion src/common/localization/es-cl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,6 @@ export const spanish: IAppStrings = {
}
},
farItems: {
share: "Compartir proyecto",
zoom: {
zoomOut: "Alejar",
zoomIn: "Acercarse",
Expand Down Expand Up @@ -634,6 +633,7 @@ export const spanish: IAppStrings = {
}
},
shareProject: {
name: "Compartir proyecto",
errors: {
cannotDecodeString: "¡No se puede decodificar la cadena compartida! Por favor, verifique si su cadena ha sido modificada.",
connectionNotFound: "Conexión no encontrada. Agregue la conexión del proyecto compartido a sus conexiones.",
Expand Down
2 changes: 1 addition & 1 deletion src/common/strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,6 @@ export interface IAppStrings {
},
},
farItems: {
share: string,
zoom: {
zoomOut: string,
zoomIn: string,
Expand Down Expand Up @@ -533,6 +532,7 @@ export interface IAppStrings {
modelNotFound: IErrorMetadata,
};
shareProject: {
name: string,
errors: {
cannotDecodeString: string,
connectionNotFound: string,
Expand Down
43 changes: 7 additions & 36 deletions src/react/components/pages/editorPage/canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
EditorMode, IAssetMetadata,
IProject, IRegion, RegionType,
AssetType, ILabelData, ILabel,
ITag, IAsset, IFormRegion, FeatureCategory, FieldType, FieldFormat, ISecurityToken,
ITag, IAsset, IFormRegion, FeatureCategory, FieldType, FieldFormat,
} from "../../../../models/applicationState";
import CanvasHelpers from "./canvasHelpers";
import { AssetPreview } from "../../common/assetPreview/assetPreview";
Expand All @@ -30,13 +30,11 @@ import Alert from "../../common/alert/alert";
import * as pdfjsLib from "pdfjs-dist";
import Polygon from "ol/geom/Polygon";
import HtmlFileReader from "../../../../common/htmlFileReader";
import { parseTiffData, renderTiffToCanvas, loadImageToCanvas, getSasFolderString, fixedEncodeURIComponent } from "../../../../common/utils";
import { parseTiffData, renderTiffToCanvas, loadImageToCanvas } from "../../../../common/utils";
import { constants } from "../../../../common/constants";
import { CanvasCommandBar } from "./canvasCommandBar";
import { TooltipHost, ITooltipHostStyles } from "@fluentui/react";
import { IAppSettings } from '../../../../models/applicationState';
import { toast } from "react-toastify";
import { strings } from "../../../../common/strings";


pdfjsLib.GlobalWorkerOptions.workerSrc = constants.pdfjsWorkerSrc(pdfjsLib.version);
Expand All @@ -58,7 +56,6 @@ export interface ICanvasProps extends React.Props<Canvas> {
onRunningOCRStatusChanged?: (isRunning: boolean) => void;
onTagChanged?: (oldTag: ITag, newTag: ITag) => void;
runOcrForAllDocs?: (runForAllDocs: boolean) => void;
shareProject?: () => void;
onAssetDeleted?: () => void;
}

Expand Down Expand Up @@ -114,7 +111,6 @@ export default class Canvas extends React.Component<ICanvasProps, ICanvasState>
lockedTags: [],
hoveredLabel: null,
appSettings: null,
shareProject: null,
};

public state: ICanvasState = {
Expand Down Expand Up @@ -234,8 +230,6 @@ export default class Canvas extends React.Component<ICanvasProps, ICanvasState>
handleRunOcr={this.runOcr}
handleAssetDeleted={this.props.onAssetDeleted}
handleRunOcrForAllDocuments={this.runOcrForAllDocuments}
handleShareProject={this.shareProject}
connectionType={this.props.project.sourceConnection.providerType}
/>
<ImageMap
ref={(ref) => this.imageMap = ref}
Expand Down Expand Up @@ -317,29 +311,6 @@ export default class Canvas extends React.Component<ICanvasProps, ICanvasState>
this.props.runOcrForAllDocs(true);
}

// creates URI for sharing project
private shareProject = (): void => {
const project: IProject = this.props.project;
const sasFolder: string = getSasFolderString(project.sourceConnection.providerOptions["sas"]);
const projectToken: ISecurityToken = this.props.appSettings.securityTokens
.find((securityToken) => securityToken.name === project.securityToken);
const shareProjectString: string = JSON.stringify({
sasFolder,
projectName: project.name,
token: { name: project.securityToken, key: projectToken.key }
});

this.copyToClipboard(shareProjectString)
}

private async copyToClipboard(value: string) {
const clipboard = (navigator as any).clipboard;
if (clipboard && clipboard.writeText) {
await clipboard.writeText(btoa(value));
toast.success(strings.shareProject.copy.success);
}
}

public updateSize() {
this.imageMap.updateSize();
}
Expand Down Expand Up @@ -503,10 +474,10 @@ export default class Canvas extends React.Component<ICanvasProps, ICanvasState>
selectedFeatures.map(this.imageMap.removeFeature);

const allCheckboxFeatures = this.imageMap.getAllCheckboxFeatures();
const selectdCheckboxFeatures = allCheckboxFeatures
const selectedCheckboxFeatures = allCheckboxFeatures
.filter((feature) => !feature.get("isOcrProposal"))
.filter((feature) => checkboxRegions.findIndex((region) => region.id === feature.get("id")) !== -1);
selectdCheckboxFeatures.map(this.imageMap.removeCheckboxFeature);
selectedCheckboxFeatures.map(this.imageMap.removeCheckboxFeature);

const getAllLabelledFeatures = this.imageMap.getAllLabelFeatures();
const selectedLabelledFeatures = getAllLabelledFeatures
Expand Down Expand Up @@ -1625,7 +1596,7 @@ export default class Canvas extends React.Component<ICanvasProps, ICanvasState>
features.forEach((feature) => feature.changed());
}

private createRegion(boundingBox: number[], text: string, tagName: string, pangeNumber: number) {
private createRegion(boundingBox: number[], text: string, tagName: string, pageNumber: number) {
const xAxisValues = boundingBox.filter((value, index) => index % 2 === 0);
const yAxisValues = boundingBox.filter((value, index) => index % 2 === 1);
const left = Math.min(...xAxisValues);
Expand All @@ -1643,7 +1614,7 @@ export default class Canvas extends React.Component<ICanvasProps, ICanvasState>
const tag = this.props.project.tags.find((tag) => tag.name === tagName);

const newRegion = {
id: this.createRegionIdFromBoundingBox(boundingBox, pangeNumber),
id: this.createRegionIdFromBoundingBox(boundingBox, pageNumber),
type: RegionType.Polygon,
category: tag.type === FieldType.SelectionMark ? FeatureCategory.Checkbox : FeatureCategory.Text,
tags: [tagName],
Expand All @@ -1655,7 +1626,7 @@ export default class Canvas extends React.Component<ICanvasProps, ICanvasState>
},
points,
value: text,
pageNumber: pangeNumber,
pageNumber,
};
return newRegion;
}
Expand Down
10 changes: 0 additions & 10 deletions src/react/components/pages/editorPage/canvasCommandBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ interface ICanvasCommandBarProps {
handleRunOcr: () => void;
handleRunOcrForAllDocuments: () => void;
handleLayerChange: (layer: string) => void;
handleShareProject: () => void;
connectionType: string;
handleAssetDeleted?: () => void;
layers: any;
}
Expand Down Expand Up @@ -97,14 +95,6 @@ export const CanvasCommandBar: React.FunctionComponent<ICanvasCommandBarProps> =
iconProps: { iconName: "More" },
subMenuProps: {
items: [
{
key: "shareProject",
text: strings.editorPage.canvas.canvasCommandBar.farItems.share,
disabled: props.connectionType !== "azureBlobStorage",
iconProps: { iconName: "Share" },
className: props.connectionType !== "azureBlobStorage" ? "disabled" : "",
onClick: () => props.handleShareProject(),
},
{
key: 'divider_0',
itemType: ContextualMenuItemType.Divider,
Expand Down
19 changes: 19 additions & 0 deletions src/react/components/shell/shareProjectButton.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@import '../../../assets/sass/theme.scss';

.share-button {
background-color: transparent;
height: 100%;
width: 100%;
border-radius: 0;
&:hover{
background-color: $lighter-3;
}
&.is-disabled {
.ms-Icon {
color: $darker-5;
font-size: 1rem;

}
}
}

75 changes: 75 additions & 0 deletions src/react/components/shell/shareProjectButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from 'react';
import { getSasFolderString } from "../../../common/utils";
import { IProject, IAppSettings, ISecurityToken, IApplicationState } from "../../../models/applicationState";
import { connect } from "react-redux";
import { toast } from "react-toastify";
import { IconButton, Customizer, ICustomizations } from "@fluentui/react";
import { strings } from "../../../common/strings";
import { getDarkGreyTheme } from "../../../common/themes";
import "./shareProjectButton.scss"


interface IShareProps {
appSettings?: IAppSettings,
currentProject?: IProject;
}
interface IShareState {
appSettings: IAppSettings,
currentProject: IProject;
}

function mapStateToProps(state: IApplicationState) {
return {
appSettings: state.appSettings,
currentProject: state.currentProject,
};
}

const dark: ICustomizations = {
settings: {
theme: getDarkGreyTheme(),
},
scopedSettings: {},
};

@connect(mapStateToProps)
export default class ShareProjectButton extends React.Component<IShareProps> {

// creates string for sharing project
private shareProject = (): void => {
const currentProject: IProject = this.props.currentProject;
const sasFolder: string = getSasFolderString(currentProject.sourceConnection.providerOptions["sas"]);
const projectToken: ISecurityToken = this.props.appSettings.securityTokens
.find((securityToken: { name: string; }) => securityToken.name === currentProject.securityToken);
const shareProjectString: string = JSON.stringify({
sasFolder,
projectName: currentProject.name,
token: { name: currentProject.securityToken, key: projectToken.key }
});

this.copyToClipboard(shareProjectString)
}

private async copyToClipboard(value: string) {
const clipboard = (navigator as any).clipboard;
if (clipboard && clipboard.writeText) {
await clipboard.writeText(btoa(value));
toast.success(strings.shareProject.copy.success);
}
}

render() {
return (
<Customizer {...dark}>
<IconButton
className="share-button"
ariaLabel={strings.shareProject.name}
iconProps={{ iconName: "Share" }}
disabled={this.props.currentProject && this.props.currentProject.sourceConnection.providerType === "azureBlobStorage" ? false : true}
title={strings.shareProject.name}
onClick={this.shareProject}
/>
</Customizer>
)
}
}

0 comments on commit 78996ea

Please sign in to comment.