From 72a0ddebb081cf812356c9fb77f24bb7663e235b Mon Sep 17 00:00:00 2001 From: lublagg Date: Mon, 26 Aug 2024 15:09:26 -0400 Subject: [PATCH 01/14] Add new UI workflow for setting up collaboration (PT-18801442) --- src/App.css | 88 +++++++++++++++++++++++++- src/App.tsx | 174 +++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 213 insertions(+), 49 deletions(-) diff --git a/src/App.css b/src/App.css index a6569a3..baacd02 100755 --- a/src/App.css +++ b/src/App.css @@ -6,12 +6,20 @@ margin: 10px; } +.App.sharing { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; +} + .App li { margin-bottom: 12px; } .App.sharing .callout { text-align: center; + font-style: italic; } .App.sharing .callout.shareId { @@ -23,4 +31,82 @@ .App .error-message { color: red; -} \ No newline at end of file +} + +input { + height: 20px; +} + +.form-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: 200px; +} + +.button-stack { + gap: 15px; +} + +.input-row { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + align-self: flex-start; +} + +.input-row input { + width: 75px; +} + +.input-stack { + display: flex; + flex-direction: column; + align-self: flex-start; +} + +.input-stack input { + margin-left: 25px; +} + +.select-stack { + display: flex; + flex-direction: column; + align-self: flex-start; + width: 100%; +} + +.select-stack select { + align-self: center; +} + +.merge-button { + margin-top: 10px; +} + +.button-row { + display: flex; + flex-direction: row; + justify-content: center; + gap: 10px; + align-self: flex-end; +} + +button { + cursor: pointer; +} + +.cancel-button { + padding: 0px; + border: none; + border-radius: 5px; + color: blue; + background-color: #fff; + text-decoration: underline; +} + +.leave-collaboration { + margin-top: 10px; +} diff --git a/src/App.tsx b/src/App.tsx index ff7a816..a1aa846 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,12 +12,13 @@ import { DataContext, CodapItem, CodapRequest } from "./lib/types"; const kPluginName = "Collaborative Data Sharing"; const kVersion = pkg.version; const kInitialDimensions = { - width: 350, - height: 400 + width: 450, + height: 325 }; + const kSharedDimensions = { - width: 350, - height: 200 + width: 400, + height: 350 }; const kShareIdLength = 6; @@ -35,6 +36,10 @@ interface IState extends ISaveState { joinShareId: string; isInProcessOfSharing: boolean; showJoinShareError: boolean; + allowOthersToJoin?: boolean; + joinOtherTable?: boolean; + mergeTable?: boolean; + createNewTable?: boolean; } let database: DB; @@ -52,7 +57,7 @@ export default class App extends Component { lastSelectedDataContext: "", joinShareId: "", isInProcessOfSharing: false, - showJoinShareError: false + showJoinShareError: false, }; public componentDidMount() { @@ -92,53 +97,126 @@ export default class App extends Component { renderForm() { const { availableDataContexts, selectedDataContext, lastSelectedDataContext, - personalDataLabel, lastPersonalDataLabel, joinShareId, isInProcessOfSharing } = this.state; + personalDataLabel, lastPersonalDataLabel, joinShareId, + allowOthersToJoin, joinOtherTable, mergeTable, createNewTable } = this.state; const availableContextOptions = availableDataContexts.map((dc: DataContext) => ); const selectedContextOption = selectedDataContext || lastSelectedDataContext || kNewSharedTable; - const readyToInitiateShare = (!!personalDataLabel || !!lastPersonalDataLabel) && !isInProcessOfSharing; - const readyToJoinShare = readyToInitiateShare && (joinShareId.length === kShareIdLength); + + const showFirstStep = !allowOthersToJoin && !joinOtherTable && !mergeTable && !createNewTable; + const showFirstAllowOthersToJoinOptions = allowOthersToJoin && !joinOtherTable && !mergeTable && !createNewTable; return (
- To create or join a collaborative table -
    -
  1. - Select a table to share or create a new one + {showFirstStep && +
    + +
    +
    + ----- or ----- +
    +
    + +
    +
    + } + { joinOtherTable && +
    +
    +
    1. Enter the code to join another group:
    + +
    +
    +
    2. Provide a name or label for your data.
    + +
    +
    + + +
    +
    + } + { showFirstAllowOthersToJoinOptions && +
    + +
    + ----- or ----- +
    + +
    + +
    +
    + } + { mergeTable && +
    +
    +
    1. Select a table to merge with the shared group:
    -
  2. -
  3. - Provide a name or label for grouping -
    +
    +
    2. Enter the code of the group to join:
    + +
    +
    +
    3. Provide a name or label for your data.
    -
  4. -
  5. - Invite others to join your table or join another group -
    -
    - -
    -
    - or -
    -
    - Enter code to join another group: - - -
    +
    + + +
    +
    + } + { createNewTable && +
    +
    +
    1. Select a table for others to join:
    +
    -
  6. -
+
+
2. Provide a name or label for your data:
+ +
+
+ + +
+
+ } {this.renderErrorMessage()} ); @@ -159,19 +237,19 @@ export default class App extends Component { const tableName = dataContext ? dataContext.title : selectedDataContext; return (
-
- Table collaboration enabled for -
-
- {tableName} +
+ Table collaboration enabled for: +
+ {tableName} +
-
- Others can join this table by using the code +
+ Others can join this table by using the code: +
+ {shareId} +
-
- {shareId} -
-
+
@@ -263,7 +341,7 @@ export default class App extends Component { await Codap.removeItems(selectedDataContext, [items[0]]); items.shift(); } - + // write non-empty user items to firebase database.writeUserItems(personalDataKey, items.filter(item => !Codap.isEmptyUserItem(item))); return items; From 703074093cee26fbe5bdd5dd8f43c0d9708170a7 Mon Sep 17 00:00:00 2001 From: lublagg Date: Mon, 26 Aug 2024 16:08:56 -0400 Subject: [PATCH 02/14] Update cypress test. --- cypress/e2e/workspace.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/e2e/workspace.test.ts b/cypress/e2e/workspace.test.ts index 1209625..443ee4c 100644 --- a/cypress/e2e/workspace.test.ts +++ b/cypress/e2e/workspace.test.ts @@ -8,7 +8,7 @@ context("Test the overall app", () => { describe("Desktop functionalities", () => { it("renders with text", () => { - ae.getApp().invoke("text").should("include", "To create or join a collaborative table"); + ae.getApp().invoke("text").should("include", "Allow others to join your table"); }); }); }); From 0359777ccd94d2794c817ce2eb5ba413c8064db8 Mon Sep 17 00:00:00 2001 From: lublagg Date: Tue, 27 Aug 2024 12:45:43 -0400 Subject: [PATCH 03/14] Styling + form fixes. --- src/App.css | 83 +++++++++++++++++++++++++++++++++++++++++++------- src/App.tsx | 75 +++++++++++++++++++++++++++------------------ src/index.css | 4 +-- src/index.html | 1 + 4 files changed, 119 insertions(+), 44 deletions(-) diff --git a/src/App.css b/src/App.css index baacd02..cab9088 100755 --- a/src/App.css +++ b/src/App.css @@ -1,9 +1,20 @@ +:root { + --teal: #177991; + --dark-teal: #105262; + --dark-teal-2: #016082; + --teal-light-1: #93d5e4; + --teal-light-2: #b7e2ec; + --teal-light-3: #cdebf2; + --charcoal: #080808; +} + .App { - margin: 10px 4px; + color: var(--charcoal); } .App div { - margin: 10px; + padding: 10px; + font-size: 12px; } .App.sharing { @@ -34,17 +45,40 @@ } input { - height: 20px; + height: 16px; + border: 1px solid var(--teal); + border-radius: 3px; +} + +input:focus { + border: 1px solid var(--teal); + background-color: var(--teal-light-3); + outline-width: 0px; } .form-container { display: flex; flex-direction: column; align-items: center; - justify-content: center; + justify-content: flex-start; min-height: 200px; } +.separator { + width: 95%; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; +} + +div.separator-line { + border: .5px solid var(--charcoal); + width: 100%; + height: 0px; + padding: 0px; +} + .button-stack { gap: 15px; } @@ -79,11 +113,14 @@ input { } .select-stack select { - align-self: center; -} - -.merge-button { - margin-top: 10px; + align-self: flex-start; + margin-left: 25px; + border: 1px solid var(--teal); + padding: 2px; + border-radius: 3px; + cursor: pointer; + font-family: 'Montserrat', sans-serif; + font-size: 12px; } .button-row { @@ -96,15 +133,39 @@ input { button { cursor: pointer; + background-color: var(--teal-light-3); + /* color: white; */ + border-radius: 5px; + border-width: 1px; + color: var(--charcoal); + border-color: var(--charcoal); + padding: 5px 10px; + font-family: 'Montserrat', sans-serif; + font-size: 12px; +} + +button:hover { + background-color: var(--teal-light-2); +} + +button:active { + background-color: var(--teal-light-1); } .cancel-button { padding: 0px; border: none; border-radius: 5px; - color: blue; - background-color: #fff; + color: var(--dark-teal-2); + background-color: #ffffff; text-decoration: underline; + cursor: pointer; +} + +.cancel-button:hover { + background-color: #ffffff; + cursor: pointer; + color: var(--dark-teal) } .leave-collaboration { diff --git a/src/App.tsx b/src/App.tsx index a1aa846..a7d2fbe 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,8 +12,8 @@ import { DataContext, CodapItem, CodapRequest } from "./lib/types"; const kPluginName = "Collaborative Data Sharing"; const kVersion = pkg.version; const kInitialDimensions = { - width: 450, - height: 325 + width: 420, + height: 350 }; const kSharedDimensions = { @@ -40,6 +40,7 @@ interface IState extends ISaveState { joinOtherTable?: boolean; mergeTable?: boolean; createNewTable?: boolean; + newTableName?: string; } let database: DB; @@ -98,7 +99,7 @@ export default class App extends Component { renderForm() { const { availableDataContexts, selectedDataContext, lastSelectedDataContext, personalDataLabel, lastPersonalDataLabel, joinShareId, - allowOthersToJoin, joinOtherTable, mergeTable, createNewTable } = this.state; + allowOthersToJoin, joinOtherTable, mergeTable, createNewTable, newTableName } = this.state; const availableContextOptions = availableDataContexts.map((dc: DataContext) => ); @@ -111,16 +112,18 @@ export default class App extends Component {
{showFirstStep &&
-
-
-
- ----- or ----- +
+
+
or
+
-
-
@@ -128,12 +131,12 @@ export default class App extends Component { } { joinOtherTable &&
-
+
1. Enter the code to join another group:
-
2. Provide a name or label for your data.
+
2. Provide a name or label for your data:
@@ -149,15 +152,21 @@ export default class App extends Component { } { showFirstAllowOthersToJoinOptions &&
- -
- ----- or ----- +
+ +
+
+
+
or
+
+
+
+
-
-
+
2. Enter the code of the group to join:
-
3. Provide a name or label for your data.
+
3. Provide a name or label for your data:
@@ -196,11 +205,12 @@ export default class App extends Component { } { createNewTable &&
-
-
1. Select a table for others to join:
- +
+
1. Enter a name for the table:
+ this.setState({ newTableName: e.target.value })} + />
2. Provide a name or label for your data:
@@ -383,15 +393,15 @@ export default class App extends Component { initiateShare = async () => { await this.updatePersonalDataLabelAndKey(); - const {selectedDataContext, personalDataKey, personalDataLabel } = this.state; + const {selectedDataContext, personalDataKey, personalDataLabel, createNewTable, newTableName } = this.state; let dataContextName: string; this.setState({ isInProcessOfSharing: true }); try { - if (!selectedDataContext || (selectedDataContext === kNewSharedTable)) { + if (createNewTable) { // create new data context for sharing - const newContext = await Codap.createDataContext({title: kNewDataContextTitle}); + const newContext = await Codap.createDataContext({title: newTableName? newTableName : kNewDataContextTitle}); if (newContext) { dataContextName = newContext.name; this.updateSelectedDataContext(dataContextName); @@ -501,7 +511,12 @@ export default class App extends Component { this.setState({ shareId: null, personalDataLabel: "", - joinShareId: "" + joinShareId: "", + allowOthersToJoin: undefined, + joinOtherTable: undefined, + mergeTable: undefined, + createNewTable: undefined + }); database.leaveSharedTable(); }; diff --git a/src/index.css b/src/index.css index 66bebec..04d6490 100755 --- a/src/index.css +++ b/src/index.css @@ -1,9 +1,7 @@ body { margin: 0; padding: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; + font-family: 'Montserrat', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } \ No newline at end of file diff --git a/src/index.html b/src/index.html index fc62129..20601dc 100644 --- a/src/index.html +++ b/src/index.html @@ -5,6 +5,7 @@ Codap Shared Table Plugin +
From 3c1d9d4e7f5425c4b4b70983ca5cc84f0744b5aa Mon Sep 17 00:00:00 2001 From: lublagg Date: Tue, 27 Aug 2024 14:32:17 -0400 Subject: [PATCH 04/14] Use if/else statements + separate components for form pages. --- src/App.tsx | 242 +++++++-------------- src/constants.ts | 33 +++ src/types.ts | 19 ++ src/ui-pages/allow-others-to-join-page.tsx | 36 +++ src/ui-pages/create-new-table-page.tsx | 41 ++++ src/ui-pages/first-page.tsx | 29 +++ src/ui-pages/join-other-table.tsx | 39 ++++ src/ui-pages/merge-table-page.tsx | 50 +++++ 8 files changed, 327 insertions(+), 162 deletions(-) create mode 100644 src/constants.ts create mode 100644 src/types.ts create mode 100644 src/ui-pages/allow-others-to-join-page.tsx create mode 100644 src/ui-pages/create-new-table-page.tsx create mode 100644 src/ui-pages/first-page.tsx create mode 100644 src/ui-pages/join-other-table.tsx create mode 100644 src/ui-pages/merge-table-page.tsx diff --git a/src/App.tsx b/src/App.tsx index a7d2fbe..c7e8ded 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,52 +1,35 @@ import pDebounce from "p-debounce"; import React, { Component, ChangeEvent } from "react"; import randomize from "randomatic"; -import pkg from "../package.json"; import "./App.css"; -import { CodapHelper as Codap, ISaveState } from "./lib/codap-helper"; +import { CodapHelper as Codap, } from "./lib/codap-helper"; import codapInterface from "./lib/CodapInterface"; import { DB } from "./lib/db"; import { DBSharedTable } from "./lib/db-types"; import { DataContext, CodapItem, CodapRequest } from "./lib/types"; - -const kPluginName = "Collaborative Data Sharing"; -const kVersion = pkg.version; -const kInitialDimensions = { - width: 420, - height: 350 -}; - -const kSharedDimensions = { - width: 400, - height: 350 -}; - -const kShareIdLength = 6; - -const kNewSharedTable = "new-table"; -const kNewDataContextTitle = "Collaborative Table"; - -interface IState extends ISaveState { - id: string; - availableDataContexts: DataContext[]; - selectedDataContext: string; - personalDataLabel: string; - personalDataKey: string; - shareId?: string; - joinShareId: string; - isInProcessOfSharing: boolean; - showJoinShareError: boolean; - allowOthersToJoin?: boolean; - joinOtherTable?: boolean; - mergeTable?: boolean; - createNewTable?: boolean; - newTableName?: string; -} +import { kInitialDimensions, kPluginName, kSharedDimensions, kVersion, kNewDataContextTitle, + kNewSharedTable, kShareIdLength } from "./constants"; +import { IState } from "./types"; +import { FirstPage } from "./ui-pages/first-page"; +import { JoinOtherTablePage } from "./ui-pages/join-other-table"; +import { AllowOthersToJoinPage } from "./ui-pages/allow-others-to-join-page"; +import { MergeTablePage } from "./ui-pages/merge-table-page"; +import { CreateNewTablePage } from "./ui-pages/create-new-table-page" let database: DB; export default class App extends Component { + constructor() { + super({}); + this.setState = this.setState.bind(this); + this.handleJoinShareIdChange = this.handleJoinShareIdChange.bind(this); + this.handleDataLabelChange = this.handleDataLabelChange.bind(this); + this.joinShare = this.joinShare.bind(this); + this.handleDataContextChange = this.handleDataContextChange.bind(this); + this.initiateShare = this.initiateShare.bind(this); + } + public state: IState = { id: "", availableDataContexts: [], @@ -61,6 +44,7 @@ export default class App extends Component { showJoinShareError: false, }; + public componentDidMount() { Codap.initializePlugin(kPluginName, kVersion, kInitialDimensions) .then(loadState => { @@ -96,137 +80,71 @@ export default class App extends Component { } } - renderForm() { - const { availableDataContexts, selectedDataContext, lastSelectedDataContext, - personalDataLabel, lastPersonalDataLabel, joinShareId, - allowOthersToJoin, joinOtherTable, mergeTable, createNewTable, newTableName } = this.state; - const availableContextOptions = availableDataContexts.map((dc: DataContext) => - - ); - const selectedContextOption = selectedDataContext || lastSelectedDataContext || kNewSharedTable; - + renderFormPage() { + const { availableDataContexts, selectedDataContext, lastSelectedDataContext, allowOthersToJoin, + joinOtherTable, mergeTable, createNewTable } = this.state; const showFirstStep = !allowOthersToJoin && !joinOtherTable && !mergeTable && !createNewTable; const showFirstAllowOthersToJoinOptions = allowOthersToJoin && !joinOtherTable && !mergeTable && !createNewTable; + if (showFirstStep) { + return ( + + ) + } else if (joinOtherTable) { + return ( + + ) + } else if (showFirstAllowOthersToJoinOptions) { + return ( + + ) + } else if (mergeTable) { + const availableContextOptions = availableDataContexts.map((dc: DataContext) => + + ); + const selectedContextOption = selectedDataContext || lastSelectedDataContext || kNewSharedTable; + return ( + + ) + } else if (createNewTable) { + return ( + + ) + } + } + + renderForm() { return (
- {showFirstStep && -
-
- -
-
-
-
or
-
-
-
- -
-
- } - { joinOtherTable && -
-
-
1. Enter the code to join another group:
- -
-
-
2. Provide a name or label for your data:
- -
-
- - -
-
- } - { showFirstAllowOthersToJoinOptions && -
-
- -
-
-
-
or
-
-
-
- -
-
- -
-
- } - { mergeTable && -
-
-
1. Select a table to merge with the shared group:
- -
-
-
2. Enter the code of the group to join:
- -
-
-
3. Provide a name or label for your data:
- -
-
- - -
-
- } - { createNewTable && -
-
-
1. Enter a name for the table:
- this.setState({ newTableName: e.target.value })} - /> -
-
-
2. Provide a name or label for your data:
- -
-
- - -
-
- } + {this.renderFormPage()} {this.renderErrorMessage()}
); diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..d89f052 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,33 @@ + +import pkg from "../package.json"; + +export const kPluginName = "Collaborative Data Sharing"; +export const kVersion = pkg.version; +export const kInitialDimensions = { + width: 420, + height: 350 +}; + +export const kSharedDimensions = { + width: 400, + height: 350 +}; + +export const kShareIdLength = 6; + +export const kNewSharedTable = "new-table"; +export const kNewDataContextTitle = "Collaborative Table"; + + +export const ALLOW_OTHERS_TO_JOIN = "Allow others to join your table"; +export const JOIN_SOMEONE_ELSES_TABLE = "Join someone else's table"; +export const ENTER_CODE_TO_JOIN_GROUP = "Enter the code to join another group:"; +export const PROVIDE_NAME_OR_LABEL = "Provide a name or label for your data:"; +export const MERGE_TABLES = "Merge one of your tables with the table being joined"; +export const CREATE_NEW_TABLE = "Create new table"; +export const OR = "or"; +export const CANCEL = "cancel"; +export const SELECT_TABLE_TO_MERGE = "Select a table to merge with the shared group:"; +export const ENTER_CODE_OF_GROUP = "Enter the code of the group to join:"; +export const BEGIN_COLLABORATION = "Begin Collaboration"; +export const ENTER_NAME_FOR_TABLE = "Enter a name for the table:"; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..917accb --- /dev/null +++ b/src/types.ts @@ -0,0 +1,19 @@ +import { ISaveState } from "./lib/codap-helper"; +import { DataContext } from "./lib/types"; + +export interface IState extends ISaveState { + id: string; + availableDataContexts: DataContext[]; + selectedDataContext: string; + personalDataLabel: string; + personalDataKey: string; + shareId?: string; + joinShareId: string; + isInProcessOfSharing: boolean; + showJoinShareError: boolean; + allowOthersToJoin?: boolean; + joinOtherTable?: boolean; + mergeTable?: boolean; + createNewTable?: boolean; + newTableName?: string; +} diff --git a/src/ui-pages/allow-others-to-join-page.tsx b/src/ui-pages/allow-others-to-join-page.tsx new file mode 100644 index 0000000..1892246 --- /dev/null +++ b/src/ui-pages/allow-others-to-join-page.tsx @@ -0,0 +1,36 @@ +import React from "react"; +import { CANCEL, CREATE_NEW_TABLE, MERGE_TABLES, OR } from "../constants"; +import { IState } from "../types"; + +interface AllowOthersToJoinPageProps { + updateState: (state: Partial) => void; +} + +export const AllowOthersToJoinPage = ({updateState}: AllowOthersToJoinPageProps) => { + return ( +
+
+ +
+
+
+
{OR}
+
+
+
+ +
+
+ +
+
+ ) +}; diff --git a/src/ui-pages/create-new-table-page.tsx b/src/ui-pages/create-new-table-page.tsx new file mode 100644 index 0000000..7c5cabd --- /dev/null +++ b/src/ui-pages/create-new-table-page.tsx @@ -0,0 +1,41 @@ +import React from "react"; +import { BEGIN_COLLABORATION, CANCEL, ENTER_NAME_FOR_TABLE, PROVIDE_NAME_OR_LABEL } from "../constants"; +import { IState } from "../types"; + +interface CreateNewTablePageProps { + newTableName: string; + updateState: (state: Partial) => void; + personalDataLabel: string; + lastPersonalDataLabel: string; + handleDataLabelChange: (event: React.ChangeEvent) => void; + initiateShare: () => void; +} + +export const CreateNewTablePage = (props: CreateNewTablePageProps) => { + const { newTableName, updateState, personalDataLabel, lastPersonalDataLabel, + handleDataLabelChange, initiateShare} = props; + return ( +
+
+
{ENTER_NAME_FOR_TABLE}
+ updateState({ newTableName: e.target.value })} + /> +
+
+
{PROVIDE_NAME_OR_LABEL}
+ +
+
+ + +
+
+ ) +}; diff --git a/src/ui-pages/first-page.tsx b/src/ui-pages/first-page.tsx new file mode 100644 index 0000000..449f6d2 --- /dev/null +++ b/src/ui-pages/first-page.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { IState } from '../types'; +import { ALLOW_OTHERS_TO_JOIN, JOIN_SOMEONE_ELSES_TABLE, OR } from '../constants'; + +interface FirstPageProps { + updateState: (state: Partial) => void; +} + +export const FirstPage = ({updateState}: FirstPageProps) => { + return ( +
+
+ +
+
+
+
{OR}
+
+
+
+ +
+
+ ) +}; diff --git a/src/ui-pages/join-other-table.tsx b/src/ui-pages/join-other-table.tsx new file mode 100644 index 0000000..0e385b2 --- /dev/null +++ b/src/ui-pages/join-other-table.tsx @@ -0,0 +1,39 @@ +import React from "react"; +import { IState } from "../types"; +import { CANCEL, PROVIDE_NAME_OR_LABEL, BEGIN_COLLABORATION, ENTER_CODE_TO_JOIN_GROUP } from "../constants"; + +interface JoinOtherTableProps { + joinShareId: string; + personalDataLabel: string; + lastPersonalDataLabel: string; + handleJoinShareIdChange: (event: React.ChangeEvent) => void; + handleDataLabelChange: (event: React.ChangeEvent) => void; + joinShare: () => void; + updateState: (state: Partial) => void; +} + +export const JoinOtherTablePage = (props: JoinOtherTableProps) => { + const { joinShareId, personalDataLabel, lastPersonalDataLabel, handleJoinShareIdChange, + handleDataLabelChange, joinShare, updateState } = props; + return ( +
+
+
{ENTER_CODE_TO_JOIN_GROUP}
+ +
+
+
{PROVIDE_NAME_OR_LABEL}
+ +
+
+ + +
+
+ ) +}; diff --git a/src/ui-pages/merge-table-page.tsx b/src/ui-pages/merge-table-page.tsx new file mode 100644 index 0000000..1e71386 --- /dev/null +++ b/src/ui-pages/merge-table-page.tsx @@ -0,0 +1,50 @@ +import React from "react"; +import { BEGIN_COLLABORATION, CANCEL, ENTER_CODE_OF_GROUP, PROVIDE_NAME_OR_LABEL, + SELECT_TABLE_TO_MERGE } from "../constants"; +import { IState } from "../types"; + +interface MergeTablePageProps { + selectedContextOption: string; + availableContextOptions: JSX.Element[]; + joinShareId: string; + personalDataLabel: string; + lastPersonalDataLabel: string; + handleDataContextChange: (event: React.ChangeEvent) => void; + handleJoinShareIdChange: (event: React.ChangeEvent) => void; + handleDataLabelChange: (event: React.ChangeEvent) => void; + initiateShare: () => void; + updateState: (state: Partial) => void; +} + +export const MergeTablePage = (props: MergeTablePageProps) => { + const { selectedContextOption, availableContextOptions, joinShareId, personalDataLabel, + lastPersonalDataLabel, handleDataContextChange, handleJoinShareIdChange, handleDataLabelChange, + initiateShare, updateState } = props; + return ( +
+
+
{SELECT_TABLE_TO_MERGE}
+ +
+
+
{ENTER_CODE_OF_GROUP}
+ +
+
+
{PROVIDE_NAME_OR_LABEL}
+ +
+
+ + +
+
+ ) +}; From 5366bbfa1eda86479d7581d6d5e239a8e1eab5d9 Mon Sep 17 00:00:00 2001 From: lublagg Date: Tue, 27 Aug 2024 16:28:02 -0400 Subject: [PATCH 05/14] Disable begin collaboration button when info is not filled out. --- src/App.css | 9 +++++++++ src/ui-pages/create-new-table-page.tsx | 2 +- src/ui-pages/join-other-table.tsx | 2 +- src/ui-pages/merge-table-page.tsx | 5 ++++- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/App.css b/src/App.css index cab9088..c0a99b3 100755 --- a/src/App.css +++ b/src/App.css @@ -6,6 +6,8 @@ --teal-light-2: #b7e2ec; --teal-light-3: #cdebf2; --charcoal: #080808; + --charcoal-light: #333333; + --charcoal-light-5: #f2f2f2; } .App { @@ -152,6 +154,13 @@ button:active { background-color: var(--teal-light-1); } +button:disabled { + opacity: 0.7; + background-color: var(--charcoal-light-5); + color: var(--charcoal-light); + cursor: not-allowed; +} + .cancel-button { padding: 0px; border: none; diff --git a/src/ui-pages/create-new-table-page.tsx b/src/ui-pages/create-new-table-page.tsx index 7c5cabd..7603288 100644 --- a/src/ui-pages/create-new-table-page.tsx +++ b/src/ui-pages/create-new-table-page.tsx @@ -34,7 +34,7 @@ export const CreateNewTablePage = (props: CreateNewTablePageProps) => { onClick={() => updateState({ createNewTable: false })}> {CANCEL} - +
) diff --git a/src/ui-pages/join-other-table.tsx b/src/ui-pages/join-other-table.tsx index 0e385b2..bab9d25 100644 --- a/src/ui-pages/join-other-table.tsx +++ b/src/ui-pages/join-other-table.tsx @@ -32,7 +32,7 @@ export const JoinOtherTablePage = (props: JoinOtherTableProps) => { onClick={() => updateState({ joinOtherTable: false })}> {CANCEL} - +
) diff --git a/src/ui-pages/merge-table-page.tsx b/src/ui-pages/merge-table-page.tsx index 1e71386..05f1183 100644 --- a/src/ui-pages/merge-table-page.tsx +++ b/src/ui-pages/merge-table-page.tsx @@ -43,7 +43,10 @@ export const MergeTablePage = (props: MergeTablePageProps) => { onClick={() => updateState({ mergeTable: false })}> {CANCEL} - +
) From f458385786969265d10eeac2f8045204e6450ef0 Mon Sep 17 00:00:00 2001 From: lublagg Date: Wed, 28 Aug 2024 18:05:36 -0400 Subject: [PATCH 06/14] Add new sub-pages + update text. --- src/App.css | 2 + src/App.tsx | 89 ++++++++++++------- src/constants.ts | 27 ++++-- src/types.ts | 4 +- src/ui-pages/allow-others-to-join-page.tsx | 10 +-- src/ui-pages/create-new-table-page.tsx | 4 +- src/ui-pages/first-page.tsx | 4 +- ...able-page.tsx => join-and-merge-table.tsx} | 30 +++---- .../join-other-table-options-page.tsx | 36 ++++++++ ...her-table.tsx => join-without-merging.tsx} | 18 ++-- src/ui-pages/share-existing-table.tsx | 46 ++++++++++ 11 files changed, 195 insertions(+), 75 deletions(-) rename src/ui-pages/{merge-table-page.tsx => join-and-merge-table.tsx} (70%) create mode 100644 src/ui-pages/join-other-table-options-page.tsx rename src/ui-pages/{join-other-table.tsx => join-without-merging.tsx} (77%) create mode 100644 src/ui-pages/share-existing-table.tsx diff --git a/src/App.css b/src/App.css index c0a99b3..4bce545 100755 --- a/src/App.css +++ b/src/App.css @@ -12,6 +12,7 @@ .App { color: var(--charcoal); + font-weight: 500; } .App div { @@ -144,6 +145,7 @@ button { padding: 5px 10px; font-family: 'Montserrat', sans-serif; font-size: 12px; + font-weight: 500; } button:hover { diff --git a/src/App.tsx b/src/App.tsx index c7e8ded..d713a16 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,10 +11,12 @@ import { kInitialDimensions, kPluginName, kSharedDimensions, kVersion, kNewDataC kNewSharedTable, kShareIdLength } from "./constants"; import { IState } from "./types"; import { FirstPage } from "./ui-pages/first-page"; -import { JoinOtherTablePage } from "./ui-pages/join-other-table"; +import { JoinAndMergeTableForm } from "./ui-pages/join-and-merge-table"; import { AllowOthersToJoinPage } from "./ui-pages/allow-others-to-join-page"; -import { MergeTablePage } from "./ui-pages/merge-table-page"; +import { ShareExistingTablePage } from "./ui-pages/share-existing-table"; import { CreateNewTablePage } from "./ui-pages/create-new-table-page" +import { JoinOtherTableOptionsPage } from "./ui-pages/join-other-table-options-page"; +import { JoinWithoutMerging } from "./ui-pages/join-without-merging"; let database: DB; @@ -82,23 +84,25 @@ export default class App extends Component { renderFormPage() { const { availableDataContexts, selectedDataContext, lastSelectedDataContext, allowOthersToJoin, - joinOtherTable, mergeTable, createNewTable } = this.state; - const showFirstStep = !allowOthersToJoin && !joinOtherTable && !mergeTable && !createNewTable; - const showFirstAllowOthersToJoinOptions = allowOthersToJoin && !joinOtherTable && !mergeTable && !createNewTable; + joinOtherTable, shareExistingTable, joinAndMergeTable, createNewTable, + joinWithoutMerging } = this.state; + const showFirstStep = !allowOthersToJoin && !joinOtherTable; + const noSelectedSubOptions = !shareExistingTable && !createNewTable && !joinAndMergeTable && !joinWithoutMerging; + const showFirstAllowOthersToJoinOptions = allowOthersToJoin && !joinOtherTable && noSelectedSubOptions; + const showFirstJoinOtherTableOptions = !allowOthersToJoin && joinOtherTable && noSelectedSubOptions; + + const availableContextOptions = availableDataContexts.map((dc: DataContext) => + + ); + const selectedContextOption = selectedDataContext || lastSelectedDataContext || kNewSharedTable; if (showFirstStep) { return ( ) - } else if (joinOtherTable) { + } else if (showFirstJoinOtherTableOptions) { return ( - ) @@ -108,25 +112,46 @@ export default class App extends Component { updateState={this.setState} /> ) - } else if (mergeTable) { - const availableContextOptions = availableDataContexts.map((dc: DataContext) => - - ); - const selectedContextOption = selectedDataContext || lastSelectedDataContext || kNewSharedTable; - return ( - - ) + } else if (joinAndMergeTable) { + return ( + + ) + } else if (joinWithoutMerging) { + return ( + + ) + } else if (shareExistingTable) { + return ( + + ) } else if (createNewTable) { return (
-
@@ -27,8 +27,8 @@ export const AllowOthersToJoinPage = ({updateState}: AllowOthersToJoinPageProps)
diff --git a/src/ui-pages/create-new-table-page.tsx b/src/ui-pages/create-new-table-page.tsx index 7603288..0679a3f 100644 --- a/src/ui-pages/create-new-table-page.tsx +++ b/src/ui-pages/create-new-table-page.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { BEGIN_COLLABORATION, CANCEL, ENTER_NAME_FOR_TABLE, PROVIDE_NAME_OR_LABEL } from "../constants"; +import { BEGIN_COLLABORATION, BACK, ENTER_NAME_FOR_TABLE, PROVIDE_NAME_OR_LABEL } from "../constants"; import { IState } from "../types"; interface CreateNewTablePageProps { @@ -32,7 +32,7 @@ export const CreateNewTablePage = (props: CreateNewTablePageProps) => {
diff --git a/src/ui-pages/first-page.tsx b/src/ui-pages/first-page.tsx index 449f6d2..32aa35a 100644 --- a/src/ui-pages/first-page.tsx +++ b/src/ui-pages/first-page.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { IState } from '../types'; -import { ALLOW_OTHERS_TO_JOIN, JOIN_SOMEONE_ELSES_TABLE, OR } from '../constants'; +import { BEGIN_SHARING_TABLE, JOIN_SOMEONE_ELSES_TABLE, OR } from '../constants'; interface FirstPageProps { updateState: (state: Partial) => void; @@ -11,7 +11,7 @@ export const FirstPage = ({updateState}: FirstPageProps) => {
diff --git a/src/ui-pages/merge-table-page.tsx b/src/ui-pages/join-and-merge-table.tsx similarity index 70% rename from src/ui-pages/merge-table-page.tsx rename to src/ui-pages/join-and-merge-table.tsx index 05f1183..a23c94e 100644 --- a/src/ui-pages/merge-table-page.tsx +++ b/src/ui-pages/join-and-merge-table.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { BEGIN_COLLABORATION, CANCEL, ENTER_CODE_OF_GROUP, PROVIDE_NAME_OR_LABEL, - SELECT_TABLE_TO_MERGE } from "../constants"; +import { BEGIN_COLLABORATION, BACK, PROVIDE_NAME_OR_LABEL, + ENTER_CODE_OF_GROUP, SELECT_TABLE_TO_MERGE} from "../constants"; import { IState } from "../types"; interface MergeTablePageProps { @@ -12,14 +12,14 @@ interface MergeTablePageProps { handleDataContextChange: (event: React.ChangeEvent) => void; handleJoinShareIdChange: (event: React.ChangeEvent) => void; handleDataLabelChange: (event: React.ChangeEvent) => void; - initiateShare: () => void; + joinShare: () => void; updateState: (state: Partial) => void; } -export const MergeTablePage = (props: MergeTablePageProps) => { - const { selectedContextOption, availableContextOptions, joinShareId, personalDataLabel, - lastPersonalDataLabel, handleDataContextChange, handleJoinShareIdChange, handleDataLabelChange, - initiateShare, updateState } = props; +export const JoinAndMergeTableForm = (props: MergeTablePageProps) => { + const { selectedContextOption, availableContextOptions, personalDataLabel, + lastPersonalDataLabel, handleDataContextChange, handleDataLabelChange, + joinShare, joinShareId, updateState, handleJoinShareIdChange } = props; return (
@@ -28,24 +28,24 @@ export const MergeTablePage = (props: MergeTablePageProps) => { {availableContextOptions}
-
-
{ENTER_CODE_OF_GROUP}
- -
{PROVIDE_NAME_OR_LABEL}
+
+
{ENTER_CODE_OF_GROUP}
+ +
diff --git a/src/ui-pages/join-other-table-options-page.tsx b/src/ui-pages/join-other-table-options-page.tsx new file mode 100644 index 0000000..0fcd633 --- /dev/null +++ b/src/ui-pages/join-other-table-options-page.tsx @@ -0,0 +1,36 @@ +import React from "react"; +import { BACK, JOIN_AND_MERGE, OR, JOIN_WITHOUT_MERGING } from "../constants"; +import { IState } from "../types"; + +interface AllowOthersToJoinPageProps { + updateState: (state: Partial) => void; +} + +export const JoinOtherTableOptionsPage = ({updateState}: AllowOthersToJoinPageProps) => { + return ( +
+
+ +
+
+
+
{OR}
+
+
+
+ +
+
+ +
+
+ ) +}; diff --git a/src/ui-pages/join-other-table.tsx b/src/ui-pages/join-without-merging.tsx similarity index 77% rename from src/ui-pages/join-other-table.tsx rename to src/ui-pages/join-without-merging.tsx index bab9d25..9626ad6 100644 --- a/src/ui-pages/join-other-table.tsx +++ b/src/ui-pages/join-without-merging.tsx @@ -1,8 +1,8 @@ import React from "react"; import { IState } from "../types"; -import { CANCEL, PROVIDE_NAME_OR_LABEL, BEGIN_COLLABORATION, ENTER_CODE_TO_JOIN_GROUP } from "../constants"; +import { BACK, PROVIDE_NAME_OR_LABEL, BEGIN_COLLABORATION, ENTER_CODE_OF_GROUP } from "../constants"; -interface JoinOtherTableProps { +interface JoinWithoutMergingProps { joinShareId: string; personalDataLabel: string; lastPersonalDataLabel: string; @@ -12,25 +12,25 @@ interface JoinOtherTableProps { updateState: (state: Partial) => void; } -export const JoinOtherTablePage = (props: JoinOtherTableProps) => { +export const JoinWithoutMerging = (props: JoinWithoutMergingProps) => { const { joinShareId, personalDataLabel, lastPersonalDataLabel, handleJoinShareIdChange, handleDataLabelChange, joinShare, updateState } = props; return (
-
-
{ENTER_CODE_TO_JOIN_GROUP}
- -
{PROVIDE_NAME_OR_LABEL}
+
+
{ENTER_CODE_OF_GROUP}
+ +
diff --git a/src/ui-pages/share-existing-table.tsx b/src/ui-pages/share-existing-table.tsx new file mode 100644 index 0000000..c60e138 --- /dev/null +++ b/src/ui-pages/share-existing-table.tsx @@ -0,0 +1,46 @@ +import React from "react"; +import { BEGIN_COLLABORATION, BACK, PROVIDE_NAME_OR_LABEL, SELECT_TABLE_TO_SHARE } from "../constants"; +import { IState } from "../types"; + +interface MergeTablePageProps { + selectedContextOption: string; + availableContextOptions: JSX.Element[]; + personalDataLabel: string; + lastPersonalDataLabel: string; + handleDataContextChange: (event: React.ChangeEvent) => void; + handleDataLabelChange: (event: React.ChangeEvent) => void; + initiateShare: () => void; + updateState: (state: Partial) => void; +} + +export const ShareExistingTablePage = (props: MergeTablePageProps) => { + const { selectedContextOption, availableContextOptions, personalDataLabel, + lastPersonalDataLabel, handleDataContextChange, handleDataLabelChange, + initiateShare, updateState } = props; + return ( +
+
+
{SELECT_TABLE_TO_SHARE}
+ +
+
+
{PROVIDE_NAME_OR_LABEL}
+ +
+
+ + +
+
+ ) +}; From f2fcc134acc2e6302c844d5d63af59265a12d8b8 Mon Sep 17 00:00:00 2001 From: lublagg Date: Wed, 28 Aug 2024 18:13:31 -0400 Subject: [PATCH 07/14] Update variable + component names for clarity. --- src/App.tsx | 35 +++++++++---------- src/types.ts | 4 +-- src/ui-pages/first-page.tsx | 4 +-- src/ui-pages/join-and-merge-table.tsx | 4 +-- ...able-options-page.tsx => join-options.tsx} | 6 ++-- src/ui-pages/share-existing-table.tsx | 4 +-- ...new-table-page.tsx => share-new-table.tsx} | 4 +-- ...ers-to-join-page.tsx => share-options.tsx} | 6 ++-- 8 files changed, 33 insertions(+), 34 deletions(-) rename src/ui-pages/{join-other-table-options-page.tsx => join-options.tsx} (78%) rename src/ui-pages/{create-new-table-page.tsx => share-new-table.tsx} (92%) rename src/ui-pages/{allow-others-to-join-page.tsx => share-options.tsx} (78%) diff --git a/src/App.tsx b/src/App.tsx index d713a16..4592bf4 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,11 +11,11 @@ import { kInitialDimensions, kPluginName, kSharedDimensions, kVersion, kNewDataC kNewSharedTable, kShareIdLength } from "./constants"; import { IState } from "./types"; import { FirstPage } from "./ui-pages/first-page"; -import { JoinAndMergeTableForm } from "./ui-pages/join-and-merge-table"; -import { AllowOthersToJoinPage } from "./ui-pages/allow-others-to-join-page"; -import { ShareExistingTablePage } from "./ui-pages/share-existing-table"; -import { CreateNewTablePage } from "./ui-pages/create-new-table-page" -import { JoinOtherTableOptionsPage } from "./ui-pages/join-other-table-options-page"; +import { JoinAndMergeTable } from "./ui-pages/join-and-merge-table"; +import { ShareOptions } from "./ui-pages/share-options"; +import { ShareExistingTable } from "./ui-pages/share-existing-table"; +import { ShareNewTable } from "./ui-pages/share-new-table" +import { JoinOptions } from "./ui-pages/join-options"; import { JoinWithoutMerging } from "./ui-pages/join-without-merging"; let database: DB; @@ -83,13 +83,12 @@ export default class App extends Component { } renderFormPage() { - const { availableDataContexts, selectedDataContext, lastSelectedDataContext, allowOthersToJoin, - joinOtherTable, shareExistingTable, joinAndMergeTable, createNewTable, - joinWithoutMerging } = this.state; - const showFirstStep = !allowOthersToJoin && !joinOtherTable; + const { availableDataContexts, selectedDataContext, lastSelectedDataContext, shareTable, joinTable, + shareExistingTable, joinAndMergeTable, createNewTable, joinWithoutMerging } = this.state; + const showFirstStep = !shareTable && !joinTable; const noSelectedSubOptions = !shareExistingTable && !createNewTable && !joinAndMergeTable && !joinWithoutMerging; - const showFirstAllowOthersToJoinOptions = allowOthersToJoin && !joinOtherTable && noSelectedSubOptions; - const showFirstJoinOtherTableOptions = !allowOthersToJoin && joinOtherTable && noSelectedSubOptions; + const showShareTableOptions = shareTable && !joinTable && noSelectedSubOptions; + const showJoinTableOptions = !shareTable && joinTable && noSelectedSubOptions; const availableContextOptions = availableDataContexts.map((dc: DataContext) => @@ -100,21 +99,21 @@ export default class App extends Component { return ( ) - } else if (showFirstJoinOtherTableOptions) { + } else if (showJoinTableOptions) { return ( - ) - } else if (showFirstAllowOthersToJoinOptions) { + } else if (showShareTableOptions) { return ( - ) } else if (joinAndMergeTable) { return ( - { return (
-
@@ -20,7 +20,7 @@ export const FirstPage = ({updateState}: FirstPageProps) => {
-
diff --git a/src/ui-pages/join-and-merge-table.tsx b/src/ui-pages/join-and-merge-table.tsx index a23c94e..0f1f1a6 100644 --- a/src/ui-pages/join-and-merge-table.tsx +++ b/src/ui-pages/join-and-merge-table.tsx @@ -3,7 +3,7 @@ import { BEGIN_COLLABORATION, BACK, PROVIDE_NAME_OR_LABEL, ENTER_CODE_OF_GROUP, SELECT_TABLE_TO_MERGE} from "../constants"; import { IState } from "../types"; -interface MergeTablePageProps { +interface JoinAndMergeTableProps { selectedContextOption: string; availableContextOptions: JSX.Element[]; joinShareId: string; @@ -16,7 +16,7 @@ interface MergeTablePageProps { updateState: (state: Partial) => void; } -export const JoinAndMergeTableForm = (props: MergeTablePageProps) => { +export const JoinAndMergeTable = (props: JoinAndMergeTableProps) => { const { selectedContextOption, availableContextOptions, personalDataLabel, lastPersonalDataLabel, handleDataContextChange, handleDataLabelChange, joinShare, joinShareId, updateState, handleJoinShareIdChange } = props; diff --git a/src/ui-pages/join-other-table-options-page.tsx b/src/ui-pages/join-options.tsx similarity index 78% rename from src/ui-pages/join-other-table-options-page.tsx rename to src/ui-pages/join-options.tsx index 0fcd633..edbe63d 100644 --- a/src/ui-pages/join-other-table-options-page.tsx +++ b/src/ui-pages/join-options.tsx @@ -2,11 +2,11 @@ import React from "react"; import { BACK, JOIN_AND_MERGE, OR, JOIN_WITHOUT_MERGING } from "../constants"; import { IState } from "../types"; -interface AllowOthersToJoinPageProps { +interface JoinOptionsProps { updateState: (state: Partial) => void; } -export const JoinOtherTableOptionsPage = ({updateState}: AllowOthersToJoinPageProps) => { +export const JoinOptions = ({updateState}: JoinOptionsProps) => { return (
@@ -27,7 +27,7 @@ export const JoinOtherTableOptionsPage = ({updateState}: AllowOthersToJoinPagePr
diff --git a/src/ui-pages/share-existing-table.tsx b/src/ui-pages/share-existing-table.tsx index c60e138..6d3fff2 100644 --- a/src/ui-pages/share-existing-table.tsx +++ b/src/ui-pages/share-existing-table.tsx @@ -2,7 +2,7 @@ import React from "react"; import { BEGIN_COLLABORATION, BACK, PROVIDE_NAME_OR_LABEL, SELECT_TABLE_TO_SHARE } from "../constants"; import { IState } from "../types"; -interface MergeTablePageProps { +interface ShareExistingTableProps { selectedContextOption: string; availableContextOptions: JSX.Element[]; personalDataLabel: string; @@ -13,7 +13,7 @@ interface MergeTablePageProps { updateState: (state: Partial) => void; } -export const ShareExistingTablePage = (props: MergeTablePageProps) => { +export const ShareExistingTable = (props: ShareExistingTableProps) => { const { selectedContextOption, availableContextOptions, personalDataLabel, lastPersonalDataLabel, handleDataContextChange, handleDataLabelChange, initiateShare, updateState } = props; diff --git a/src/ui-pages/create-new-table-page.tsx b/src/ui-pages/share-new-table.tsx similarity index 92% rename from src/ui-pages/create-new-table-page.tsx rename to src/ui-pages/share-new-table.tsx index 0679a3f..525ccaf 100644 --- a/src/ui-pages/create-new-table-page.tsx +++ b/src/ui-pages/share-new-table.tsx @@ -2,7 +2,7 @@ import React from "react"; import { BEGIN_COLLABORATION, BACK, ENTER_NAME_FOR_TABLE, PROVIDE_NAME_OR_LABEL } from "../constants"; import { IState } from "../types"; -interface CreateNewTablePageProps { +interface ShareNewTableProps { newTableName: string; updateState: (state: Partial) => void; personalDataLabel: string; @@ -11,7 +11,7 @@ interface CreateNewTablePageProps { initiateShare: () => void; } -export const CreateNewTablePage = (props: CreateNewTablePageProps) => { +export const ShareNewTable = (props: ShareNewTableProps) => { const { newTableName, updateState, personalDataLabel, lastPersonalDataLabel, handleDataLabelChange, initiateShare} = props; return ( diff --git a/src/ui-pages/allow-others-to-join-page.tsx b/src/ui-pages/share-options.tsx similarity index 78% rename from src/ui-pages/allow-others-to-join-page.tsx rename to src/ui-pages/share-options.tsx index 8f6a0e6..44f9fd7 100644 --- a/src/ui-pages/allow-others-to-join-page.tsx +++ b/src/ui-pages/share-options.tsx @@ -2,11 +2,11 @@ import React from "react"; import { BACK, CREATE_NEW_TABLE, SHARE_EXISTING_TABLE, OR } from "../constants"; import { IState } from "../types"; -interface AllowOthersToJoinPageProps { +interface ShareOptionsProps { updateState: (state: Partial) => void; } -export const AllowOthersToJoinPage = ({updateState}: AllowOthersToJoinPageProps) => { +export const ShareOptions = ({updateState}: ShareOptionsProps) => { return (
@@ -27,7 +27,7 @@ export const AllowOthersToJoinPage = ({updateState}: AllowOthersToJoinPageProps)
From 2e10484b098d7dd02684776adc93c1f278ae15be Mon Sep 17 00:00:00 2001 From: lublagg Date: Thu, 29 Aug 2024 14:45:35 -0400 Subject: [PATCH 08/14] Move functions out of constructor into renderForm() --- cypress/e2e/workspace.test.ts | 2 +- src/App.tsx | 55 +++++++++++++++++------------------ 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/cypress/e2e/workspace.test.ts b/cypress/e2e/workspace.test.ts index 443ee4c..4f22545 100644 --- a/cypress/e2e/workspace.test.ts +++ b/cypress/e2e/workspace.test.ts @@ -8,7 +8,7 @@ context("Test the overall app", () => { describe("Desktop functionalities", () => { it("renders with text", () => { - ae.getApp().invoke("text").should("include", "Allow others to join your table"); + ae.getApp().invoke("text").should("include", "Begin sharing a table"); }); }); }); diff --git a/src/App.tsx b/src/App.tsx index 4592bf4..499c810 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -22,16 +22,6 @@ let database: DB; export default class App extends Component { - constructor() { - super({}); - this.setState = this.setState.bind(this); - this.handleJoinShareIdChange = this.handleJoinShareIdChange.bind(this); - this.handleDataLabelChange = this.handleDataLabelChange.bind(this); - this.joinShare = this.joinShare.bind(this); - this.handleDataContextChange = this.handleDataContextChange.bind(this); - this.initiateShare = this.initiateShare.bind(this); - } - public state: IState = { id: "", availableDataContexts: [], @@ -90,6 +80,13 @@ export default class App extends Component { const showShareTableOptions = shareTable && !joinTable && noSelectedSubOptions; const showJoinTableOptions = !shareTable && joinTable && noSelectedSubOptions; + const setState = (state: Partial) => this.setState(state); + const handleJoinShareIdChange = (event: ChangeEvent) => this.handleJoinShareIdChange(event); + const handleDataLabelChange = (event: ChangeEvent) => this.handleDataLabelChange(event); + const joinShare = () => this.joinShare(); + const handleDataContextChange = (event: ChangeEvent) => this.handleDataContextChange(event); + const initiateShare = () => this.initiateShare(); + const availableContextOptions = availableDataContexts.map((dc: DataContext) => ); @@ -97,18 +94,18 @@ export default class App extends Component { if (showFirstStep) { return ( - + ) } else if (showJoinTableOptions) { return ( ) } else if (showShareTableOptions) { return ( ) } else if (joinAndMergeTable) { @@ -117,11 +114,11 @@ export default class App extends Component { joinShareId={this.state.joinShareId} personalDataLabel={this.state.personalDataLabel} lastPersonalDataLabel={this.state.lastPersonalDataLabel} - handleJoinShareIdChange={this.handleJoinShareIdChange} - handleDataLabelChange={this.handleDataLabelChange} - handleDataContextChange={this.handleDataContextChange} - joinShare={this.joinShare} - updateState={this.setState} + handleJoinShareIdChange={handleJoinShareIdChange} + handleDataLabelChange={handleDataLabelChange} + handleDataContextChange={handleDataContextChange} + joinShare={joinShare} + updateState={setState} selectedContextOption={selectedContextOption} availableContextOptions={availableContextOptions} /> @@ -132,10 +129,10 @@ export default class App extends Component { joinShareId={this.state.joinShareId} personalDataLabel={this.state.personalDataLabel} lastPersonalDataLabel={this.state.lastPersonalDataLabel} - handleJoinShareIdChange={this.handleJoinShareIdChange} - handleDataLabelChange={this.handleDataLabelChange} - joinShare={this.joinShare} - updateState={this.setState} + handleJoinShareIdChange={handleJoinShareIdChange} + handleDataLabelChange={handleDataLabelChange} + joinShare={joinShare} + updateState={setState} /> ) } else if (shareExistingTable) { @@ -145,21 +142,21 @@ export default class App extends Component { availableContextOptions={availableContextOptions} personalDataLabel={this.state.personalDataLabel} lastPersonalDataLabel={this.state.lastPersonalDataLabel} - handleDataContextChange={this.handleDataContextChange} - handleDataLabelChange={this.handleDataLabelChange} - initiateShare={this.initiateShare} - updateState={this.setState} + handleDataContextChange={handleDataContextChange} + handleDataLabelChange={handleDataLabelChange} + initiateShare={initiateShare} + updateState={setState} /> ) } else if (createNewTable) { return ( ) } From 90aff1c35388818b1ad55e8fa5a54cd81c78250a Mon Sep 17 00:00:00 2001 From: lublagg Date: Tue, 3 Sep 2024 19:02:02 -0400 Subject: [PATCH 09/14] Reset UI state on leaveShare. --- src/App.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 499c810..8f38307 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -451,11 +451,13 @@ export default class App extends Component { shareId: null, personalDataLabel: "", joinShareId: "", - allowOthersToJoin: undefined, - joinOtherTable: undefined, - mergeTable: undefined, - createNewTable: undefined - + shareTable: undefined, + joinTable: undefined, + shareExistingTable: undefined, + createNewTable: undefined, + joinAndMergeTable: undefined, + joinWithoutMerging: undefined, + newTableName: undefined }); database.leaveSharedTable(); }; From 729ed7402f9c88b521529bfd3e776826a297831e Mon Sep 17 00:00:00 2001 From: lublagg Date: Wed, 4 Sep 2024 11:41:12 -0400 Subject: [PATCH 10/14] Enable collaboration if lastPersonalDataLabel exists. --- src/App.tsx | 101 ++++++++++++++------------ src/ui-pages/join-and-merge-table.tsx | 2 +- src/ui-pages/join-without-merging.tsx | 6 +- src/ui-pages/share-existing-table.tsx | 8 +- src/ui-pages/share-new-table.tsx | 9 ++- 5 files changed, 70 insertions(+), 56 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 8f38307..5faf8ce 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,7 +8,7 @@ import { DB } from "./lib/db"; import { DBSharedTable } from "./lib/db-types"; import { DataContext, CodapItem, CodapRequest } from "./lib/types"; import { kInitialDimensions, kPluginName, kSharedDimensions, kVersion, kNewDataContextTitle, - kNewSharedTable, kShareIdLength } from "./constants"; + kShareIdLength } from "./constants"; import { IState } from "./types"; import { FirstPage } from "./ui-pages/first-page"; import { JoinAndMergeTable } from "./ui-pages/join-and-merge-table"; @@ -85,12 +85,17 @@ export default class App extends Component { const handleDataLabelChange = (event: ChangeEvent) => this.handleDataLabelChange(event); const joinShare = () => this.joinShare(); const handleDataContextChange = (event: ChangeEvent) => this.handleDataContextChange(event); - const initiateShare = () => this.initiateShare(); + const initiateShare = (selectedContext?: string) => { + if (selectedContext) { + this.setState({ selectedDataContext: selectedContext }); + } + this.initiateShare() + }; const availableContextOptions = availableDataContexts.map((dc: DataContext) => ); - const selectedContextOption = selectedDataContext || lastSelectedDataContext || kNewSharedTable; + const selectedContextOption = selectedDataContext || lastSelectedDataContext || availableDataContexts[0]?.name; if (showFirstStep) { return ( @@ -109,45 +114,45 @@ export default class App extends Component { /> ) } else if (joinAndMergeTable) { - return ( - - ) - } else if (joinWithoutMerging) { - return ( - - ) - } else if (shareExistingTable) { - return ( - - ) + ) + } else if (joinWithoutMerging) { + return ( + + ) + } else if (shareExistingTable) { + return ( + + ) } else if (createNewTable) { return ( { await this.updatePersonalDataLabelAndKey(); - const {joinShareId: shareId, personalDataKey, personalDataLabel, selectedDataContext } = this.state; + const {joinShareId: shareId, personalDataKey, personalDataLabel, selectedDataContext, + joinAndMergeTable } = this.state; this.setState({ isInProcessOfSharing: true }); try { @@ -393,8 +399,9 @@ export default class App extends Component { let ownDataContextName; if (sharedContextData) { const { dataContext: sharedDataContext, itemData } = sharedContextData; - const existingDataContext = selectedDataContext && (selectedDataContext !== kNewSharedTable) && - await Codap.getDataContext(selectedDataContext); + + const existingDataContext = joinAndMergeTable && selectedDataContext && + await Codap.getDataContext(selectedDataContext); if (!existingDataContext) { const newDataContext = sharedDataContext && @@ -406,8 +413,7 @@ export default class App extends Component { } else { throw new Error("failed to create data context"); } - } - else { + } else { ownDataContextName = selectedDataContext; await Codap.addNewCollaborationCollections(selectedDataContext, personalDataKey, personalDataLabel, false); await Codap.syncDataContexts(selectedDataContext, sharedDataContext, true); @@ -424,8 +430,7 @@ export default class App extends Component { if (!itemData?.[personalDataKey]) { Codap.configureUserCase(ownDataContextName, personalDataKey, personalDataLabel, true); } - } - else { + } else { Codap.moveUserItemsToLast(selectedDataContext, personalDataKey); this.writeUserItems(selectedDataContext, personalDataKey); } diff --git a/src/ui-pages/join-and-merge-table.tsx b/src/ui-pages/join-and-merge-table.tsx index 0f1f1a6..4fdedb1 100644 --- a/src/ui-pages/join-and-merge-table.tsx +++ b/src/ui-pages/join-and-merge-table.tsx @@ -44,7 +44,7 @@ export const JoinAndMergeTable = (props: JoinAndMergeTableProps) => { {BACK}
diff --git a/src/ui-pages/join-without-merging.tsx b/src/ui-pages/join-without-merging.tsx index 9626ad6..514b06a 100644 --- a/src/ui-pages/join-without-merging.tsx +++ b/src/ui-pages/join-without-merging.tsx @@ -32,7 +32,11 @@ export const JoinWithoutMerging = (props: JoinWithoutMergingProps) => { onClick={() => updateState({ joinWithoutMerging: false })}> {BACK} - +
) diff --git a/src/ui-pages/share-existing-table.tsx b/src/ui-pages/share-existing-table.tsx index 6d3fff2..df4d291 100644 --- a/src/ui-pages/share-existing-table.tsx +++ b/src/ui-pages/share-existing-table.tsx @@ -9,7 +9,7 @@ interface ShareExistingTableProps { lastPersonalDataLabel: string; handleDataContextChange: (event: React.ChangeEvent) => void; handleDataLabelChange: (event: React.ChangeEvent) => void; - initiateShare: () => void; + initiateShare: (selectedContextOption?: string) => void; updateState: (state: Partial) => void; } @@ -17,7 +17,7 @@ export const ShareExistingTable = (props: ShareExistingTableProps) => { const { selectedContextOption, availableContextOptions, personalDataLabel, lastPersonalDataLabel, handleDataContextChange, handleDataLabelChange, initiateShare, updateState } = props; - return ( + return (
{SELECT_TABLE_TO_SHARE}
@@ -37,8 +37,8 @@ export const ShareExistingTable = (props: ShareExistingTableProps) => { {BACK}
diff --git a/src/ui-pages/share-new-table.tsx b/src/ui-pages/share-new-table.tsx index 525ccaf..82ccebb 100644 --- a/src/ui-pages/share-new-table.tsx +++ b/src/ui-pages/share-new-table.tsx @@ -8,7 +8,7 @@ interface ShareNewTableProps { personalDataLabel: string; lastPersonalDataLabel: string; handleDataLabelChange: (event: React.ChangeEvent) => void; - initiateShare: () => void; + initiateShare: (selectedContextOption?: string) => void; } export const ShareNewTable = (props: ShareNewTableProps) => { @@ -34,7 +34,12 @@ export const ShareNewTable = (props: ShareNewTableProps) => { onClick={() => updateState({ createNewTable: false })}> {BACK} - +
) From bd2a4da0c08d8cb8937720319c66bb273a5dfa31 Mon Sep 17 00:00:00 2001 From: lublagg Date: Wed, 4 Sep 2024 12:21:19 -0400 Subject: [PATCH 11/14] Fix: new dataset not appearing in dropdown menu. --- src/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index 5faf8ce..05af7d7 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -93,7 +93,7 @@ export default class App extends Component { }; const availableContextOptions = availableDataContexts.map((dc: DataContext) => - + ); const selectedContextOption = selectedDataContext || lastSelectedDataContext || availableDataContexts[0]?.name; From f4f20f493137dae7e7b2f8acbf92dc5192170ec5 Mon Sep 17 00:00:00 2001 From: lublagg Date: Wed, 4 Sep 2024 13:49:49 -0400 Subject: [PATCH 12/14] Show message if there are no available contexts to share/merge. --- src/App.css | 5 +++++ src/constants.ts | 3 +++ src/ui-pages/join-and-merge-table.tsx | 14 ++++++++++---- src/ui-pages/share-existing-table.tsx | 14 ++++++++++---- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/App.css b/src/App.css index 4bce545..da1c5c4 100755 --- a/src/App.css +++ b/src/App.css @@ -47,6 +47,11 @@ color: red; } +.App .warning { + color: red; + font-style: italic; +} + input { height: 16px; border: 1px solid var(--teal); diff --git a/src/constants.ts b/src/constants.ts index fab796f..ee02d1a 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -40,3 +40,6 @@ export const ENTER_CODE_OF_GROUP = "Enter the code of the group to join:"; export const PROVIDE_NAME_OR_LABEL = "Provide a name or label for your data:"; export const BEGIN_COLLABORATION = "Begin Collaboration"; + +export const NO_TABLES_TO_MERGE = "You don't have any tables to merge. Create a new one or import a table to continue."; +export const NO_TABLES_TO_SHARE = "You don't have any tables to share. Create a new one or import a table to continue."; diff --git a/src/ui-pages/join-and-merge-table.tsx b/src/ui-pages/join-and-merge-table.tsx index 4fdedb1..b2035bd 100644 --- a/src/ui-pages/join-and-merge-table.tsx +++ b/src/ui-pages/join-and-merge-table.tsx @@ -1,6 +1,7 @@ import React from "react"; import { BEGIN_COLLABORATION, BACK, PROVIDE_NAME_OR_LABEL, - ENTER_CODE_OF_GROUP, SELECT_TABLE_TO_MERGE} from "../constants"; + ENTER_CODE_OF_GROUP, SELECT_TABLE_TO_MERGE, + NO_TABLES_TO_MERGE} from "../constants"; import { IState } from "../types"; interface JoinAndMergeTableProps { @@ -24,9 +25,14 @@ export const JoinAndMergeTable = (props: JoinAndMergeTableProps) => {
{SELECT_TABLE_TO_MERGE}
- + {availableContextOptions.length > 0 + ? + :
+ {NO_TABLES_TO_MERGE} +
+ }
{PROVIDE_NAME_OR_LABEL}
diff --git a/src/ui-pages/share-existing-table.tsx b/src/ui-pages/share-existing-table.tsx index df4d291..7330c25 100644 --- a/src/ui-pages/share-existing-table.tsx +++ b/src/ui-pages/share-existing-table.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { BEGIN_COLLABORATION, BACK, PROVIDE_NAME_OR_LABEL, SELECT_TABLE_TO_SHARE } from "../constants"; +import { BEGIN_COLLABORATION, BACK, PROVIDE_NAME_OR_LABEL, SELECT_TABLE_TO_SHARE, + NO_TABLES_TO_SHARE } from "../constants"; import { IState } from "../types"; interface ShareExistingTableProps { @@ -21,9 +22,14 @@ export const ShareExistingTable = (props: ShareExistingTableProps) => {
{SELECT_TABLE_TO_SHARE}
- + {availableContextOptions.length > 0 + ? + :
+ {NO_TABLES_TO_SHARE} +
+ }
{PROVIDE_NAME_OR_LABEL}
From 41af412be5ab1c8221b9cc9122e4ecbb66a2b4aa Mon Sep 17 00:00:00 2001 From: lublagg <89816272+lublagg@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:55:01 -0400 Subject: [PATCH 13/14] Remove commented-out line Co-authored-by: Teale Fristoe --- src/App.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/App.css b/src/App.css index da1c5c4..bb2dd58 100755 --- a/src/App.css +++ b/src/App.css @@ -142,7 +142,6 @@ div.separator-line { button { cursor: pointer; background-color: var(--teal-light-3); - /* color: white; */ border-radius: 5px; border-width: 1px; color: var(--charcoal); From 509d6ed240eef96e6c9fd6ccc0e919d7266c2d67 Mon Sep 17 00:00:00 2001 From: lublagg <89816272+lublagg@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:55:23 -0400 Subject: [PATCH 14/14] Use more succinct syntax Co-authored-by: Teale Fristoe --- src/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index 05af7d7..5b2d646 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -345,7 +345,7 @@ export default class App extends Component { try { if (createNewTable) { // create new data context for sharing - const newContext = await Codap.createDataContext({title: newTableName? newTableName : kNewDataContextTitle}); + const newContext = await Codap.createDataContext({title: newTableName ?? kNewDataContextTitle}); if (newContext) { dataContextName = newContext.name; this.updateSelectedDataContext(dataContextName);