Skip to content

Commit b17a665

Browse files
Chloe CourtoisChloe Courtois
Chloe Courtois
authored and
Chloe Courtois
committed
added copying and saving typescript funcs
1 parent e535adc commit b17a665

File tree

11 files changed

+165
-67
lines changed

11 files changed

+165
-67
lines changed

.DS_Store

0 Bytes
Binary file not shown.

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
node_modules/
2-
dist/
2+
dist/
3+
.DS_Store

assets/boost-demo-1_1.5x.gif

-12.9 MB
Binary file not shown.

assets/boost-demo-2_1.5x.gif

-29.9 MB
Binary file not shown.

assets/boost-demo-3_1.5x.gif

-5.14 MB
Binary file not shown.

manifest.xml

+13-55
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
22
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp">
3-
<Id>3bdda3cc-a36f-4ecc-9727-f12dc4361b36</Id>
3+
<Id>35e8fe18-68ea-463c-b138-52cbce24d0f8</Id>
44
<Version>1.0.0.0</Version>
5-
<ProviderName>Boost</ProviderName>
5+
<ProviderName>Contoso</ProviderName>
66
<DefaultLocale>en-US</DefaultLocale>
77
<DisplayName DefaultValue="Boost"/>
8-
<Description DefaultValue="Dev tool for typescript developers who utilize excel"/>
8+
<Description DefaultValue="Write your own Excel functions in TypeScript."/>
99
<IconUrl DefaultValue="https://localhost:3000/assets/boost-icon-32.png"/>
1010
<HighResolutionIconUrl DefaultValue="https://localhost:3000/assets/boost-icon-64.png"/>
1111
<SupportUrl DefaultValue="https://github.com/oslabs-beta/Boost/issues"/>
12-
<!-- AppDomains
13-
Domains in addition to the SourceLocation (a few lines below) that the add in will use to load pages
14-
Also lists trusted domains from which API cals can be made
15-
Specify a new AppDomain element for each domain -->
16-
17-
<!-- <AppDomains>
12+
<AppDomains>
1813
<AppDomain>https://www.contoso.com</AppDomain>
19-
</AppDomains> -->
14+
</AppDomains>
2015
<Hosts>
2116
<Host Name="Workbook"/>
2217
</Hosts>
@@ -54,38 +49,7 @@
5449
</GetStarted>
5550
<FunctionFile resid="Commands.Url"/>
5651
<ExtensionPoint xsi:type="PrimaryCommandSurface">
57-
58-
<CustomTab id="Boost.Tab">
59-
<Group id="Boost.Tab1.Group1">
60-
<Label resid="Boost.Tab.GroupLabel1" />
61-
62-
<!-- Required sizes: 16, 32, 80. Optional sizes: 20, 24, 40, 48, 64 -->
63-
<Icon>
64-
<bt:Image size="16" resid="Icon.16x16" />
65-
<bt:Image size="32" resid="Icon.32x32" />
66-
<bt:Image size="80" resid="Icon.80x80" />
67-
</Icon>
68-
<Control xsi:type="Button" id="Boost.TaskpaneButton">
69-
<Label resid="Boost.TaskpaneButton.Label1" />
70-
<Supertip>
71-
<Title resid="Boost.TaskpaneButton.Label1" />
72-
<Description resid="Boost.TaskpaneButton.Tooltip" />
73-
</Supertip>
74-
<Icon>
75-
<bt:Image size="16" resid="Icon.16x16" />
76-
<bt:Image size="32" resid="Icon.32x32" />
77-
<bt:Image size="80" resid="Icon.80x80" />
78-
</Icon>
79-
<Action xsi:type="ShowTaskpane">
80-
<TaskpaneId>ButtonId1</TaskpaneId>
81-
<SourceLocation resid="Taskpane.Url" />
82-
</Action>
83-
</Control>
84-
</Group>
85-
<Label resid="Boost.Tab.TabLabel1" />
86-
</CustomTab>
87-
88-
<!-- <OfficeTab id="TabHome">
52+
<OfficeTab id="TabHome">
8953
<Group id="CommandsGroup">
9054
<Label resid="CommandsGroup.Label"/>
9155
<Icon>
@@ -110,8 +74,7 @@
11074
</Action>
11175
</Control>
11276
</Group>
113-
</OfficeTab> -->
114-
77+
</OfficeTab>
11578
</ExtensionPoint>
11679
</DesktopFormFactor>
11780
</Host>
@@ -131,20 +94,15 @@
13194
<bt:Url id="Taskpane.Url" DefaultValue="https://localhost:3000/taskpane.html"/>
13295
</bt:Urls>
13396
<bt:ShortStrings>
134-
<bt:String id="Functions.Namespace" DefaultValue="Boost"/>
135-
<bt:String id="GetStarted.Title" DefaultValue="Get started with your sample add-in!"/>
97+
<bt:String id="Functions.Namespace" DefaultValue="CONTOSO"/>
98+
<bt:String id="GetStarted.Title" DefaultValue="Get started with Boost"/>
13699
<bt:String id="CommandsGroup.Label" DefaultValue="Commands Group"/>
137-
<bt:String id="TaskpaneButton.Label" DefaultValue="Show Default Taskpane"/>
138-
139-
<bt:String id="Boost.Tab.TabLabel1" DefaultValue="Boost"/>
140-
<bt:String id="Boost.Tab1.GroupLabel1" DefaultValue="Commands Group Boost"/>
141-
<bt:String id="Boost.TaskpaneButton.Label1" DefaultValue="Show BOOST"/>
100+
<bt:String id="TaskpaneButton.Label" DefaultValue="Boost"/>
142101
</bt:ShortStrings>
143102
<bt:LongStrings>
144-
<bt:String id="GetStarted.Description" DefaultValue="Your sample add-in loaded succesfully. Go to the HOME tab and click the 'Show Taskpane' button to get started."/>
145-
<bt:String id="TaskpaneButton.Tooltip" DefaultValue="Click to Show Taskpane" />
146-
<bt:String id="Boost.TaskpaneButton.Tooltip" DefaultValue="Click to Show Boost Taskpane"/>
103+
<bt:String id="GetStarted.Description" DefaultValue="Boost loaded succesfully. Go to the HOME tab and click the 'Show Taskpane' button to get started."/>
104+
<bt:String id="TaskpaneButton.Tooltip" DefaultValue="Click to Show Boost"/>
147105
</bt:LongStrings>
148106
</Resources>
149107
</VersionOverrides>
150-
</OfficeApp>
108+
</OfficeApp>

src/taskpane/components/App.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ https://docs.microsoft.com/en-us/office/dev/add-ins/excel/excel-add-ins-workshee
2727
export default (): JSX.Element => {
2828
const [page, setPage] = useState(<Query />);
2929
const [js, setJs] = useState("");
30+
const [library, setLibrary] = useState<any>([]);
31+
const [index, setIndex] = useState(0);
3032

3133
return (
3234
<div>
33-
<Contexts.Provider value={{ js, setJs, setPage }}>
35+
<Contexts.Provider value={{ js, setJs, setPage, library, setLibrary, index, setIndex }}>
3436
<NavBar />
3537
{page}
3638
</Contexts.Provider>

src/taskpane/components/IDE.tsx

+39-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,46 @@
1-
/* global JSX */
2-
import React, { useContext } from "react";
1+
/* global JSX console */
2+
import React, { useContext, useEffect } from "react";
33
import FuncInput from "./ide/FuncInput";
44
import FuncLibrary from "./ide/FuncLibrary";
55
import { Contexts } from "./Contexts";
66

77
export default (): JSX.Element => {
8-
const { js, setJs } = useContext(Contexts);
8+
const { js, setJs, library, setLibrary, index, setIndex } = useContext(Contexts);
9+
10+
const handleSave = () => {
11+
// const customFunc = document.getElementById()
12+
const restoreFunc = () => {
13+
setJs(js);
14+
setIndex(index);
15+
};
16+
17+
setLibrary((prev: any) => {
18+
if (index === library.length)
19+
return prev.concat(
20+
<li key={`func${index}`} onClick={restoreFunc}>
21+
{js}
22+
</li>
23+
);
24+
25+
const first = prev.slice(0, index);
26+
first.push(
27+
<li key={`func${index}`} onClick={restoreFunc}>
28+
{js}
29+
</li>
30+
);
31+
return first.concat(prev.slice(index + 1));
32+
});
33+
34+
setJs("");
35+
};
36+
37+
useEffect(() => {
38+
setIndex(library.length);
39+
}, [library]);
40+
41+
useEffect(() => {
42+
console.log("index:", index);
43+
}, [index]);
944

1045
return (
1146
<>
@@ -15,7 +50,7 @@ export default (): JSX.Element => {
1550
{/* <div className="pane">
1651
<iframe title="output" sandbox="allow-scripts" frameBorder="0" width="100%" height="100%" />
1752
</div> */}
18-
<button>SAVE</button>
53+
<button onClick={handleSave}>SAVE</button>
1954
<button onClick={() => setJs("")}>CLEAR</button>
2055
<FuncLibrary />
2156
</>

src/taskpane/components/Query.tsx

+97-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import QueryTable from "./query/QueryTable"; // reactTable
55
import reloadSheets from "./query/queryFunctions/reloadSheets"; // sets allWorksheets with useEffect
66
import handleQuery from "./query/queryFunctions/handleQuery";
77

8-
/* global JSX console document */
8+
/* global JSX console document Office Excel */
99

1010
export default (): JSX.Element => {
1111
// see allWorkSheets object in references
@@ -15,6 +15,8 @@ export default (): JSX.Element => {
1515
// hold the table
1616
const [currTable, setCurrTable] = useState<any>(<QueryTable columns={null} data={null} />);
1717

18+
const [copyHeader, setCopyHeader] = useState<any>();
19+
const [copyData, setCopyData] = useState();
1820
/**
1921
* Loads Current sheets and sets current state
2022
*/
@@ -44,6 +46,8 @@ export default (): JSX.Element => {
4446
setShowTable(true); // setting this is what causes the table to rerender, someone please tell me why
4547
// render the table with the relavent data
4648
setCurrTable(<QueryTable columns={queryHeaders} data={queryData} />);
49+
setCopyHeader(queryHeaders.map((header: any) => header.header));
50+
setCopyData(queryData);
4751
} catch (err) {
4852
console.log("Query failed:", err);
4953
// query.setAttribute("style","text-decoration-style: wavy;")
@@ -54,6 +58,96 @@ export default (): JSX.Element => {
5458
}
5559
};
5660

61+
const newSheet = async (): Promise<any> => {
62+
await makeNewSheet();
63+
await writeNewSheet();
64+
};
65+
66+
const makeNewSheet = async (): Promise<any> => {
67+
// create a new sheet with the queried information
68+
await Excel.run(async (context) => {
69+
let sheets = context.workbook.worksheets;
70+
71+
const sheetName: any = document.getElementById("sheetName");
72+
let sheet = sheets.add(sheetName.value);
73+
sheet.load("name, position");
74+
75+
await context.sync();
76+
console.log(`Added worksheet named "${sheet.name}" in position ${sheet.position}`);
77+
});
78+
79+
//currTable is a useState with the JSX element with the attributes columns and data
80+
};
81+
82+
// write sheet
83+
const writeNewSheet = async (): Promise<any> => {
84+
await Excel.run(async (context) => {
85+
const sheetName: any = document.getElementById("sheetName");
86+
let sheet = context.workbook.worksheets.getItem(sheetName.value);
87+
sheet.load("name");
88+
await context.sync();
89+
console.log("sheet", sheet.name);
90+
91+
// calculate the range
92+
const alphabet: any = {
93+
1: "A",
94+
2: "B",
95+
3: "C",
96+
4: "D",
97+
5: "E",
98+
6: "F",
99+
7: "G",
100+
8: "H",
101+
9: "I",
102+
10: "J",
103+
11: "K",
104+
12: "L",
105+
13: "M",
106+
14: "N",
107+
15: "O",
108+
16: "P",
109+
17: "Q",
110+
18: "R",
111+
19: "S",
112+
20: "T",
113+
21: "U",
114+
22: "V",
115+
23: "W",
116+
24: "X",
117+
25: "Y",
118+
26: "Z",
119+
};
120+
const findRange = (num: any) => {
121+
if (num <= 26) return alphabet[num];
122+
// else {
123+
// const times = (num / 26) >> 0;
124+
// alphabet[times -1].concat)
125+
// }
126+
};
127+
// A, AA, BA, CA
128+
const rangeString = "A1:" + findRange(copyHeader.length) + "1";
129+
let Table = sheet.tables.add(rangeString, true /*hasHeaders*/);
130+
Table.name = sheetName.value;
131+
132+
console.log("this is our header array:", copyHeader);
133+
134+
Table.getHeaderRowRange().values = [copyHeader];
135+
136+
console.log("this is our data array:", copyData);
137+
138+
Table.rows.add(-1 /*add rows to the end of the table*/, copyData);
139+
140+
if (Office.context.requirements.isSetSupported("ExcelApi", "1.2")) {
141+
sheet.getUsedRange().format.autofitColumns();
142+
sheet.getUsedRange().format.autofitRows();
143+
}
144+
145+
sheet.activate();
146+
147+
await context.sync();
148+
});
149+
};
150+
57151
return (
58152
<>
59153
<Querybox onSubmit={onSubmit} />
@@ -65,7 +159,8 @@ export default (): JSX.Element => {
65159
>
66160
CLEAR
67161
</button>
68-
{showTable ? <button>COPY</button> : null}
162+
{showTable ? <button onClick={newSheet}>COPY</button> : null}
163+
{showTable ? <input id="sheetName" placeholder="Enter sheet name here" /> : null}
69164
{showTable ? currTable : null}
70165
</>
71166
);
+11-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1-
import React from "react";
1+
import React, { useContext } from "react";
2+
import { Contexts } from "../Contexts";
3+
4+
/* global JSX */
25

36
export default (): JSX.Element => {
4-
return <div>LIBRARY</div>;
7+
const { library } = useContext(Contexts);
8+
9+
return (
10+
<div>
11+
<ul>{library}</ul>
12+
</div>
13+
);
514
};

src/taskpane/components/query/Querybox.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@ import { QueryBoxProps } from "src/types";
44
/* global JSX document */
55

66
export default (props: QueryBoxProps): JSX.Element => {
7-
const str: string = "SELECT population FROM world_population";
87
return (
98
<>
109
<textarea
1110
id="sqlQueryBox"
1211
placeholder="Enter SQL Query"
13-
defaultValue={str}
1412
onClick={() => {
1513
document.getElementById("sqlQueryBox")?.classList.remove("incorrect");
1614
}}

0 commit comments

Comments
 (0)