Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLDR-16499 Prepare to Require a CLA for contributions #3653

Merged
merged 10 commits into from
Sep 6, 2024
58 changes: 58 additions & 0 deletions tools/cldr-apps/js/src/esm/cldrCla.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as cldrClient from "../esm/cldrClient.mjs";
import * as cldrNotify from "../esm/cldrNotify.mjs";
/**
* see ClaSignature.java
* @typedef {Object} ClaSignature
* @property {boolean} corporate true if a corporate signature
* @property {string} email
* @property {string} employer
* @property {string} name
* @property {boolean} unauthorized true if cla load failed
* @property {boolean} readonly true if cla may not be modified
* @property {boolean} signed true if signed, always true when returned from getCla()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on the back end, it looks like "signed" is a Date rather than boolean?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, that should be the date signed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should that still be changed to a date, then?

*/

/** @return {ClaSignature} signed cla if present otherwise null if not accessible */
export async function getCla() {
try {
const client = await cldrClient.getClient();
const { body } = await client.apis.user.getCla();
return body;
} catch (e) {
if (e.statusCode === 401) {
return { unauthorized: true };
} else if (e.statusCode === 404) {
return { signed: false };
} else {
cldrNotify.exception(e, `trying to load CLA`);
throw e;
}
}
}

/**
* Attempt to sign.
* @throws {statusCode: 423} if the CLA may not be modified
* @throws {statusCode: 406} if there is an imput validation error
* @param {ClaSignature} cla
* @returns nothing if successful
*/
export async function signCla(cla) {
const client = await cldrClient.getClient();
const result = await client.apis.user.signCla(
{},
{
requestBody: cla,
}
);
}

/**
* Attempt to revoke.
* @throws {statusCode: 423} if the CLA may not be modified
* @throws {statusCode: 404} if the CLA was never signed
*/
export async function revokeCla() {
const client = await cldrClient.getClient();
const result = await client.apis.user.revokeCla();
}
27 changes: 17 additions & 10 deletions tools/cldr-apps/js/src/esm/cldrClient.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,19 @@ import { getSessionId } from "./cldrStatus.mjs";
import { SURVEY_TOOL_SESSION_HEADER } from "./cldrAjax.mjs";

const OAS3_ROOT = "/openapi"; // Path to the 'openapi' (sibling to cldr-apps). Needs to be a host-relative URL.
let client = null; // cached client object
const RESOLVED_ROOT = new URL(OAS3_ROOT, document.baseURI); // workaround relative resolution issues

const RESOLVED_ROOT = new URL(OAS3_ROOT, document.baseURI);
function makeClient() {
return SwaggerClient({
url: RESOLVED_ROOT,
requestInterceptor: (obj) => {
// add the session header to each request
obj.headers[SURVEY_TOOL_SESSION_HEADER] = getSessionId();
return obj;
},
});
}

/**
* Create a promise to a swagger client for ST operations.
Expand All @@ -17,15 +28,11 @@ const RESOLVED_ROOT = new URL(OAS3_ROOT, document.baseURI);
*
* @returns {Promise<SwaggerClient>}
*/
async function getClient() {
return SwaggerClient({
url: RESOLVED_ROOT,
requestInterceptor: (obj) => {
// add the session header to each request
obj.headers[SURVEY_TOOL_SESSION_HEADER] = getSessionId();
return obj;
},
});
function getClient() {
if (!client) {
client = makeClient();
}
return client;
}

export { getClient };
2 changes: 2 additions & 0 deletions tools/cldr-apps/js/src/esm/cldrComponents.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import LoginButton from "../views/LoginButton.vue";
import OverallErrors from "../views/OverallErrors.vue";
import ReportResponse from "../views/ReportResponse.vue";
import SearchButton from "../views/SearchButton.vue";
import SignCla from "../views/SignCla.vue";

// 3rd party component(s)

Expand Down Expand Up @@ -90,6 +91,7 @@ function setup(app) {
app.component("cldr-report-response", ReportResponse);
app.component("cldr-searchbutton", SearchButton);
app.component("cldr-value", CldrValue);
app.component("cldr-cla", SignCla);

// some plugins we can pull in wholesale
app.use(VueVirtualScroller);
Expand Down
4 changes: 3 additions & 1 deletion tools/cldr-apps/js/src/esm/cldrNotify.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@ const NO_TIMEOUT = 0;
*
* @param {String} message the title, displayed at the top
* @param {String} description the more detailed description
* @param {Function} onClick optional function called when clicking
*/
function open(message, description) {
function open(message, description, onClick) {
notification.open({
message: message,
description: description,
duration: MEDIUM_DURATION,
onClick,
});
}

Expand Down
1 change: 1 addition & 0 deletions tools/cldr-apps/js/src/esm/cldrText.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ const strings = {
special_add_user: "Add a Survey Tool user",
special_auto_import: "Import Old Winning Votes",
special_bulk_close_posts: "Bulk Close Posts",
special_cla: "Contributor License Agreement",
special_createAndLogin: "Create and Login",
special_default: "Missing Page",
special_dashboard: "Dashboard",
Expand Down
2 changes: 2 additions & 0 deletions tools/cldr-apps/js/src/esm/cldrVueMap.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import GenerateVxml from "../views/GenerateVxml.vue";
import LockAccount from "../views/LockAccount.vue";
import LookUp from "../views/LookUp.vue";
import MainMenu from "../views/MainMenu.vue";
import SignCla from "../views/SignCla.vue";
import TestPanel from "../views/TestPanel.vue";
import TransferVotes from "../views/TransferVotes.vue";
import UnknownPanel from "../views/UnknownPanel.vue";
Expand Down Expand Up @@ -37,6 +38,7 @@ const specialToComponentMap = {
upload: UploadPanel,
vetting_participation2: VettingParticipation2,
vsummary: VettingSummary,
cla: SignCla,
// If no match, end up here
default: UnknownPanel,
};
Expand Down
4 changes: 4 additions & 0 deletions tools/cldr-apps/js/src/md/cla.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# CLA not needed

The SurveyTool is not currently requiring a CLA.
For more details about the CLA, see [policy](https://www.unicode.org/policies/licensing_policy.html)
20 changes: 18 additions & 2 deletions tools/cldr-apps/js/src/views/MainHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
{{ unreadAnnouncementCount }}</a
>
</li>
<li v-if="coverageLevel">
<li v-if="coverageLevel && !needCla">
<label for="coverageLevel">Coverage:</label>
<select
id="coverageLevel"
Expand All @@ -40,7 +40,7 @@
</option>
</select>
</li>
<li v-if="voteCountMenu && voteCountMenu.length">
<li v-if="voteCountMenu && voteCountMenu.length && !needCla">
<label for="voteLevelChanged">Votes:</label>
<select
id="voteLevelChanged"
Expand All @@ -57,6 +57,13 @@
>Instructions</a
>
</li>
<a-alert
v-if="needCla"
@click="showCla"
message="CLA must be signed before data can be input"
type="error"
show-icon
/>
<li id="st-special-header" class="specialmessage">{{ specialHeader }}</li>
<li>
<a
Expand Down Expand Up @@ -116,6 +123,7 @@ export default {
userName: null,
voteCountMenu: null,
voteLevelChanged: 0,
needCla: false,
};
},

Expand Down Expand Up @@ -173,6 +181,10 @@ export default {
this.voteCountMenu = null;
this.voteLevelChanged = 0;
}

// only need CLA if logged in
this.needCla = !!user && !user.claSigned;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing that if DO_NOT_REQURE_CLA is true on the back end, then user.claSigned will get true (or truthy Date object?), even though that's sort of a fiction... OK, I've confirmed that

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes


this.sessionMessage = cldrStatus.getSessionMessage();
this.specialHeader = cldrStatus.getSpecialHeader();
this.stVersion = "Survey Tool " + cldrStatus.getNewVersion();
Expand All @@ -199,6 +211,10 @@ export default {
? "You have " + n + " unread announcement(s)"
: "";
},

showCla() {
window.location.replace("#cla///");
},
},
};
</script>
Expand Down
2 changes: 2 additions & 0 deletions tools/cldr-apps/js/src/views/MainMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<li>
<ul>
<li><a href="#account///">Account Settings</a></li>
<li v-if="showClaMenu"><a href="#cla///">Sign CLA</a></li>
</ul>
</li>
<li v-if="!isAdmin && !accountLocked">
Expand Down Expand Up @@ -154,6 +155,7 @@ export default {
recentActivityUrl: null,
uploadXmlUrl: null,
userId: 0,
showClaMenu: false, // off by default, see CLDR-16499
};
},

Expand Down
Loading
Loading