├── assets
├── icon-16.png
├── icon-32.png
├── icon-64.png
├── icon-80.png
├── icon-128.png
├── associate-16.png
├── associate-32.png
├── associate-80.png
├── executive-16.png
├── executive-32.png
├── executive-64.png
├── executive-80.png
├── logo-filled.png
├── partner-16.png
├── partner-32.png
├── partner-80.png
├── executive-128.png
├── sampleTaskData.json
├── sampleMeetingData.json
└── sampleEmailData.json
├── .gitignore
├── readme-images
├── outlook-add-in-ui.png
├── outlook-navigation-bar-icons.png
├── outlook-updated-navigation-bar.png
└── outlook-expanded-navigation-bar.png
├── src
└── module
│ ├── module.css
│ ├── module.html
│ └── module.js
├── LICENSE
├── README.md
├── manifest-localhost.xml
└── manifest.xml
/assets/icon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/icon-16.png
--------------------------------------------------------------------------------
/assets/icon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/icon-32.png
--------------------------------------------------------------------------------
/assets/icon-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/icon-64.png
--------------------------------------------------------------------------------
/assets/icon-80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/icon-80.png
--------------------------------------------------------------------------------
/assets/icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/icon-128.png
--------------------------------------------------------------------------------
/assets/associate-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/associate-16.png
--------------------------------------------------------------------------------
/assets/associate-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/associate-32.png
--------------------------------------------------------------------------------
/assets/associate-80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/associate-80.png
--------------------------------------------------------------------------------
/assets/executive-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/executive-16.png
--------------------------------------------------------------------------------
/assets/executive-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/executive-32.png
--------------------------------------------------------------------------------
/assets/executive-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/executive-64.png
--------------------------------------------------------------------------------
/assets/executive-80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/executive-80.png
--------------------------------------------------------------------------------
/assets/logo-filled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/logo-filled.png
--------------------------------------------------------------------------------
/assets/partner-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/partner-16.png
--------------------------------------------------------------------------------
/assets/partner-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/partner-32.png
--------------------------------------------------------------------------------
/assets/partner-80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/partner-80.png
--------------------------------------------------------------------------------
/assets/executive-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/assets/executive-128.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore certificate files.
2 | *.key
3 | *.crt
4 | *.csr
5 |
6 | # Ignore directories installed by scripts.
7 | node_modules/
8 | typings/
9 |
--------------------------------------------------------------------------------
/readme-images/outlook-add-in-ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/readme-images/outlook-add-in-ui.png
--------------------------------------------------------------------------------
/readme-images/outlook-navigation-bar-icons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/readme-images/outlook-navigation-bar-icons.png
--------------------------------------------------------------------------------
/readme-images/outlook-updated-navigation-bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/readme-images/outlook-updated-navigation-bar.png
--------------------------------------------------------------------------------
/readme-images/outlook-expanded-navigation-bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OfficeDev/Outlook-Add-in-JavaScript-ModuleExtension/HEAD/readme-images/outlook-expanded-navigation-bar.png
--------------------------------------------------------------------------------
/assets/sampleTaskData.json:
--------------------------------------------------------------------------------
1 | {
2 | "Tasks": [
3 | {
4 | "Hours": "6",
5 | "Action": "File patents from new product"
6 | },
7 | {
8 | "Hours": "2",
9 | "Action": "Prepare pending action documents for meeting"
10 | },
11 | {
12 | "Hours": "8",
13 | "Action": "Status update for corporate board"
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/assets/sampleMeetingData.json:
--------------------------------------------------------------------------------
1 | {
2 | "Appointments": [
3 | {
4 | "Attendees": "Kristy Woodard; Charlene Potter",
5 | "Hours": "4",
6 | "Subject": "Review NDA language"
7 | },
8 | {
9 | "Attendees": "Norris Frasier; Harlan Lundgren",
10 | "Hours": "6",
11 | "Subject": "Working meeting about contract with supplier"
12 | },
13 | {
14 | "Attendees": "Mark Cazares; Ruth Dalton; Allison Beasley",
15 | "Hours": "4",
16 | "Subject": "Review of pending actions"
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/assets/sampleEmailData.json:
--------------------------------------------------------------------------------
1 | {
2 | "Messages": [
3 | {
4 | "Recipients": "Norris Manzo; Susana Benson; Randy Felts",
5 | "Hours": "2",
6 | "Subject": "Product approval overview"
7 | },
8 | {
9 | "Recipients": "Allison Horne; Susana Franklin",
10 | "Hours": "1",
11 | "Subject": "Executive approval of product legal requirements"
12 | },
13 | {
14 | "Recipients": "Sonya Hogan; Jodie Norton",
15 | "Hours": "3",
16 | "Subject": "NDA approval for Level 4 and below"
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/src/module/module.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | html,
7 | body {
8 | margin-right: 24px;
9 | margin-left:24px;
10 | }
11 |
12 | .app-Title-bar {
13 |
14 | z-index: 2;
15 | padding-left: 24px;
16 | padding-top: 12px;
17 | min-height: 60px;
18 | }
19 |
20 | .app-Grid {
21 | padding-right: 48px;
22 | }
23 |
24 | .app-Grid {
25 | margin-bottom:24px
26 | }
27 |
28 | .app-Grid-row {
29 | padding: 6px;
30 | }
31 |
32 | .app-Cell-right {
33 | text-align: right;
34 | }
35 |
36 | .app-Data-display {
37 | width: 100%;
38 | height: auto;
39 | z-index: 1;
40 | min-height: 200px;
41 | padding-left: 24px;
42 | padding-top: 12px;
43 | padding-right: 24px;
44 | }
45 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) Microsoft Corporation
2 | All rights reserved.
3 |
4 | MIT License:
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/src/module/module.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Office Add-ins Outlook module extension sample
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Office Add-ins Outlook module extension sample
28 |
29 |
Meetings
30 |
31 |
32 |
33 |
Emails
34 |
35 |
36 |
37 |
Tasks
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [ARCHIVED] Compute billable hours with a module extension add-in in Outlook
2 |
3 | **Note:** This sample is archived and no longer actively maintained. Security vulnerabilities may exist in the project, or its dependencies. If you plan to reuse or run any code from this repo, be sure to perform appropriate security checks on the code or dependencies first. Don't use this project as the starting point of a production Office Add-in. Always start your production code by using the Office/SharePoint development workload in Visual Studio, or the [Yeoman generator for Office Add-ins](https://github.com/OfficeDev/generator-office), and follow security best practices as you develop the add-in.
4 |
5 | ## Summary
6 |
7 | This sample configures the [Module extension point](https://learn.microsoft.com/javascript/api/manifest/extensionpoint#module) in an Outlook add-in to compute billable hours for meetings, emails, and tasks.
8 |
9 | For documentation related to this sample, see [Module extension Outlook add-ins](https://learn.microsoft.com/office/dev/add-ins/outlook/extension-module-outlook-add-ins).
10 |
11 | ## Applies to
12 |
13 | Outlook 2016 on Windows or later.
14 |
15 | ## Prerequisites
16 |
17 | Outlook 2016 on Windows or later.
18 |
19 | ## Solution
20 |
21 | | Solution | Authors |
22 | | -------- | --------- |
23 | | Compute billable hours with a module extension add-in in Outlook. | Microsoft |
24 |
25 | ## Version history
26 |
27 | | Version | Date | Comments |
28 | | ------- | ----- | -------- |
29 | | 1.0 | 03-31-2016 | Initial release |
30 | | 1.1 | 04-04-2016 | Updated the README file |
31 | | 1.2 | 01-11-2024 | Transferred and archived sample |
32 |
33 | ## Run the sample
34 |
35 | Run this sample in Outlook on Windows using one of the following add-in file hosting options.
36 |
37 | ### Run the sample from GitHub
38 |
39 | The add-in's web files are served from this repository on GitHub.
40 |
41 | 1. Download the **manifest.xml** file from this sample to a folder on your computer.
42 | 1. Sideload the add-in manifest in Outlook on Windows by following the manual instructions in [Sideload Outlook add-ins for testing](https://learn.microsoft.com/office/dev/add-ins/outlook/sideload-outlook-add-ins-for-testing?tabs=windows#sideload-manually).
43 | 1. Follow the steps in [Try it out](#try-it-out) to test the sample.
44 |
45 | ### Run the sample from localhost
46 |
47 | If you prefer to configure a web server and host the add-in's web files from your computer, use the following steps.
48 |
49 | 1. Install a recent version of [npm](https://www.npmjs.com/get-npm) and [Node.js](https://nodejs.org/) on your computer. To verify if you've already installed these tools, run the commands `node -v` and `npm -v` in your terminal.
50 | 1. You need http-server to run the local web server. If you haven't installed this yet, you can do this with the following command.
51 |
52 | ```console
53 | npm install --global http-server
54 | ```
55 |
56 | 1. You need Office-Addin-dev-certs to generate self-signed certificates to run the local web server. If you haven't installed this yet, you can do this with the following command.
57 |
58 | ```console
59 | npm install --global office-addin-dev-certs
60 | ```
61 |
62 | 1. Clone or download this sample to a folder on your computer, then go to that folder in a console or terminal window.
63 | 1. Run the following command to generate a self-signed certificate to use for the web server.
64 |
65 | ```console
66 | npx office-addin-dev-certs install
67 | ```
68 |
69 | This command will display the folder location where it generated the certificate files.
70 | 1. Go to the folder location where the certificate files were generated, then copy the **localhost.crt** and **localhost.key** files to the cloned or downloaded sample folder.
71 | 1. Run the following command.
72 |
73 | ```console
74 | http-server -S -C localhost.crt -K localhost.key --cors . -p 3000
75 | ```
76 |
77 | The http-server will run and host the current folder's files on localhost:3000.
78 | 1. Now that your localhost web server is running, you can sideload the **manifest-localhost.xml** file provided in the sample folder. To sideload the manifest, follow the manual instructions in [Sideload Outlook add-ins for testing](https://learn.microsoft.com/office/dev/add-ins/outlook/sideload-outlook-add-ins-for-testing?tabs=windows#sideload-manually).
79 | 1. Follow the steps in [Try it out](#try-it-out) to test the sample.
80 |
81 | ## Try it out
82 |
83 | Once the add-in is loaded, perform the following steps to try it out.
84 |
85 | 1. From the Outlook navigation bar, select the **Billable Hours** add-in.
86 |
87 | The appearance of the modules on the navigation bar differ depending on whether you have a compacted or extended navigation bar.
88 |
89 | 
90 |
91 | 
92 |
93 | > **Note**: In the latest versions of Outlook on Windows, the navigation bar containing the modules appears on the left side of the client (see [New location for the Mail, Calendar, People, and other modules](https://techcommunity.microsoft.com/t5/outlook-global-customer-service/new-location-for-the-mail-calendar-people-and-other-modules/ba-p/3596278)). To access the **Billable Hours** add-in, select **More Apps** > **Billable Hours** from the navigation bar.
94 | >
95 | > 
96 | 1. The user interface of the add-in is displayed with sample data for testing. To update the computed amounts, from the ribbon, select **Associate Rate**, **Partner Rate**, or **Executive Rate**.
97 |
98 | 
99 |
100 | ## Key parts of the sample
101 |
102 | To integrate the add-in into the Outlook client's navigation bar, you must set the `xsi:type` of the **\** element to `Module`.
103 |
104 | ```xml
105 |
106 | ...
107 |
108 | ```
109 |
110 | ## Questions and feedback
111 |
112 | For general questions about developing Office Add-ins, go to [Microsoft Q&A](https://learn.microsoft.com/answers/topics/office-js-dev.html) using the office-js-dev tag.
113 |
114 | ## Copyright
115 |
116 | Copyright (c) 2024 Microsoft. All rights reserved.
117 |
118 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information, see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
119 |
--------------------------------------------------------------------------------
/manifest-localhost.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | d0c090d1-1cb0-4304-842e-1a54284a109f
4 | 1.0.0.0
5 | Contoso
6 | en-US
7 |
8 |
9 |
10 |
11 |
12 |
13 | https://www.contoso.com
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
30 |
31 | ReadWriteMailbox
32 |
33 |
34 |
35 | false
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | changeToAssociateRate
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | changeToPartnerRate
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | changeToExecutiveRate
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
--------------------------------------------------------------------------------
/src/module/module.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | (function () {
7 | "use strict"
8 | // The initialze function is run each time the page is loaded.
9 | Office.initialize = function (reason) {
10 | $(document).ready(function () {
11 | setBillingRates(127);
12 | });
13 | };
14 | })();
15 |
16 | // The next three functions change the billing rate used to
17 | // calculate the totals for each item.
18 | function changeToAssociateRate(event) {
19 | setBillingRates(127);
20 | completeEvent(event);
21 | };
22 |
23 | function changeToPartnerRate(event) {
24 | setBillingRates(237);
25 | completeEvent(event)
26 | };
27 |
28 | function changeToExecutiveRate(event) {
29 | setBillingRates(449);
30 | completeEvent(event);
31 | };
32 |
33 | function completeEvent(event) {
34 | if (event) {
35 | event.completed(true);
36 | }
37 | };
38 |
39 | var runningTotalHours;
40 | var runningTotalAmount;
41 |
42 | // Updates the user interface with the calculated
43 | // amounts to bill for each item.
44 | function setBillingRates(rate) {
45 | runningTotalHours = 0;
46 | runningTotalAmount = 0;
47 | var xhr = [
48 | setMeetingsRate(rate),
49 | setEmailRate(rate),
50 | setTasksRate(rate)
51 | ];
52 |
53 | $.when(xhr[0], xhr[1], xhr[2]).then(function () {
54 | showGrandTotal();
55 | });
56 | };
57 |
58 | // Constructs the meetings table and calculated the total
59 | // billing amount for each item and for all meetings.
60 | function setMeetingsRate(rate) {
61 | return $.getJSON("../../assets/sampleMeetingData.json", function (data) {
62 | var jsonData = data.Appointments;
63 |
64 | var dataTable = $("#app-Meetings-table");
65 | dataTable.html("");
66 |
67 | var headerRow = $('');
68 | headerRow.append(makeHeaderCell("Subject", "5"));
69 | headerRow.append(makeHeaderCell("Attendees", "5"));
70 | headerRow.append(makeHeaderCell("Hours", "1", "true"));
71 | headerRow.append(makeHeaderCell("Total", "1", "true"));
72 |
73 | dataTable.append(headerRow);
74 |
75 | var totalHours = 0;
76 | var totalAmount = 0;
77 |
78 | for (var i in jsonData) {
79 | var dataRow = $("", {
80 | "class": "ms-Grid-row app-Grid-row"
81 | });
82 | dataRow.append(makeRowCell(jsonData[i].Subject, "5"));
83 | dataRow.append(makeRowCell(jsonData[i].Attendees, "5"));
84 | dataRow.append(makeRowCell(jsonData[i].Hours, "1", "true"));
85 | dataRow.append(makeRowCell(jsonData[i].Hours * rate, "1", "true"));
86 |
87 | totalHours += Number(jsonData[i].Hours);
88 | totalAmount += rate * (jsonData[i].Hours);
89 |
90 | dataTable.append(dataRow);
91 | }
92 |
93 | dataTable.append(makeTotalRow(totalHours, totalAmount));
94 |
95 | runningTotalHours += totalHours;
96 | runningTotalAmount += totalAmount;
97 | });
98 | };
99 |
100 | // Constructs the email table and calculated the total
101 | // billing amount for each item and for all email.
102 | function setEmailRate(rate) {
103 | return $.getJSON("../../assets/sampleEmailData.json", function (data) {
104 | var jsonData = data.Messages;
105 |
106 | var dataTable = $("#app-Email-table");
107 | dataTable.html("");
108 |
109 | var headerRow = $('');
110 | headerRow.append(makeHeaderCell("Subject", "5"));
111 | headerRow.append(makeHeaderCell("Recipients", "5"));
112 | headerRow.append(makeHeaderCell("Hours", "1", "true"));
113 | headerRow.append(makeHeaderCell("Total", "1", "true"));
114 |
115 | dataTable.append(headerRow);
116 |
117 | var totalHours = 0;
118 | var totalAmount = 0;
119 |
120 | for (var i in jsonData) {
121 | var dataRow = $("", {
122 | "class": "ms-Grid-row app-Grid-row"
123 | });
124 |
125 | dataRow.append(makeRowCell(jsonData[i].Subject, "5"));
126 | dataRow.append(makeRowCell(jsonData[i].Recipients, "5"));
127 | dataRow.append(makeRowCell(jsonData[i].Hours, "1", "true"));
128 | dataRow.append(makeRowCell(jsonData[i].Hours * rate, "1", "true"));
129 |
130 | totalHours += Number(jsonData[i].Hours);
131 | totalAmount += rate * (jsonData[i].Hours);
132 |
133 | dataTable.append(dataRow);
134 | }
135 |
136 | dataTable.append(makeTotalRow(totalHours, totalAmount));
137 |
138 | runningTotalHours += totalHours;
139 | runningTotalAmount += totalAmount;
140 | });
141 | };
142 |
143 | // Constructs the tasks table and calculated the total
144 | // billing amount for each item and for all tasks.
145 | function setTasksRate(rate) {
146 | return $.getJSON("../../assets/sampleTaskData.json", function (data) {
147 | var jsonData = data.Tasks;
148 |
149 | var dataTable = $("#app-Tasks-table");
150 | dataTable.html("");
151 |
152 | var headerRow = $('');
153 | headerRow.append(makeHeaderCell("Action", "10"));
154 | headerRow.append(makeHeaderCell("Hours", "1", "true"));
155 | headerRow.append(makeHeaderCell("Total", "1", "true"));
156 |
157 | dataTable.append(headerRow);
158 |
159 | var totalHours = 0;
160 | var totalAmount = 0;
161 |
162 | for (var i in jsonData) {
163 | var dataRow = $("", {
164 | "class": "ms-Grid-row app-Grid-row"
165 | });
166 | dataRow.append(makeRowCell(jsonData[i].Action, "10"));
167 | dataRow.append(makeRowCell(jsonData[i].Hours, "1", "true"));
168 | dataRow.append(makeRowCell(jsonData[i].Hours * rate, "1", "true"));
169 |
170 | totalHours += Number(jsonData[i].Hours);
171 | totalAmount += rate * (jsonData[i].Hours);
172 |
173 | dataTable.append(dataRow);
174 | }
175 |
176 | dataTable.append(makeTotalRow(totalHours, totalAmount));
177 |
178 | runningTotalHours += totalHours;
179 | runningTotalAmount += totalAmount;
180 | });
181 | };
182 |
183 | // Creates the HTML for displaying a table header cell.
184 | function makeHeaderCell(text, width, right) {
185 | var cssClass = "ms-Grid-col ms-fontColor-themeDark ms-font-l ms-u-lg" + width;
186 |
187 | if (right) {
188 | cssClass += " app-Cell-right";
189 | }
190 |
191 | return $("", {
192 | "class": cssClass,
193 | "html": text
194 | })
195 | };
196 |
197 | // Creates the HTML for displaying a table cell.
198 | function makeRowCell(text, width, right) {
199 | var cssClass = "ms-Grid-col ms-u-md4 ms-u-lg" + width;
200 |
201 | if (right) {
202 | cssClass += " app-Cell-right";
203 | }
204 |
205 | return $("", {
206 | "class" : cssClass,
207 | "html" : text
208 | });
209 | }
210 |
211 | function makeTotalRow(totalHours, totalAmount) {
212 | var totalRow = $("", {
213 | "class": "ms-Grid-row ms-fontColor-themeDark ms-font-l app-Grid-row"
214 | });
215 |
216 | totalRow.append($("", {
217 | "class": "app-Cell-right ms-Grid-col ms-u-lg10",
218 | "html": "Totals:"
219 | }));
220 |
221 | totalRow.append($("", {
222 | "class": "app-Cell-right ms-Grid-col ms-u-lg1",
223 | "html": totalHours
224 | }));
225 |
226 | totalRow.append($("", {
227 | "class": "app-Cell-right ms-Grid-col ms-u-lg1",
228 | "html": totalAmount
229 | }));
230 |
231 | return totalRow;
232 | }
233 |
234 | // Creates the row that displays the grand total for the page.
235 | function showGrandTotal() {
236 | var totalTable = $("#app-Running-total");
237 | totalTable.html("");
238 |
239 | var totalRow = $("", {
240 | "class": "app-Title-bar ms-bgColor-themeDarker ms-fontColor-themeLighter ms-font-xxl ms-fontWeight-semibold"
241 | });
242 |
243 | totalRow.append($("", {
244 | "class": "app-Cell-right ms-Grid-col ms-u-lg10",
245 | "html": "Grand total:"
246 | }));
247 |
248 | totalRow.append($("", {
249 | "class": "app-Cell-right ms-Grid-col ms-u-lg1",
250 | "html": runningTotalHours
251 | }));
252 |
253 | totalRow.append($("", {
254 | "class": "app-Cell-right ms-Grid-col ms-u-lg1",
255 | "html": runningTotalAmount
256 | }));
257 |
258 | totalTable.append(totalRow);
259 | };
--------------------------------------------------------------------------------
/manifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | d0c090d1-1cb0-4304-842e-1a54284a109f
4 | 1.0.0.0
5 | Contoso
6 | en-US
7 |
8 |
9 |
10 |
11 |
12 |
13 | https://www.contoso.com
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
30 |
31 | ReadWriteMailbox
32 |
33 |
34 |
35 | false
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | changeToAssociateRate
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | changeToPartnerRate
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | changeToExecutiveRate
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------