The content in this section can be decided upon by either the PM or the CO.
33 |
These are the standard definitions for agile development terms in alignment with the USDS Playbook. You can also modify the definitions and add additional terms. When you are done click the "Next" button at the bottom of the page.
68 | );
69 | },
70 | });
71 |
72 | ReactDOM.render(
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | ,
83 | document.getElementById('mount')
84 | );
85 |
--------------------------------------------------------------------------------
/app/src/auth/mixin.js:
--------------------------------------------------------------------------------
1 | var _components = [ ];
2 | var _currentState = false;
3 | var _history = false;
4 | var History = require('react-router').History;
5 |
6 | function updateComponents() {
7 | _components.forEach(function(c) {
8 | c.setState({ loggedIn: _currentState });
9 | if(typeof c.loginStateChanged === 'function') {
10 | c.loginStateChanged();
11 | }
12 | });
13 | }
14 |
15 | function login(username, password, callback) {
16 | if(typeof username === 'function') {
17 | callback = username;
18 | username = undefined;
19 | password = undefined;
20 | }
21 | if(typeof callback !== 'function') {
22 | callback = function() { };
23 | }
24 |
25 | var failed = true;
26 | var opts = {
27 | type: 'GET',
28 | url: '/api/token',
29 | dataType: 'json',
30 | success: function(data) {
31 | var token = data.token;
32 | failed = false;
33 | $.ajax({
34 | type: "GET",
35 | url: "/api/token",
36 | username: token,
37 | password: 'none',
38 | success: function() {
39 | callback(token);
40 | }
41 | });
42 | },
43 | complete: function() {
44 | if(failed) {
45 | callback(false);
46 | }
47 | }
48 | };
49 |
50 | if(username && password) {
51 | opts.username = username;
52 | opts.password = password;
53 | }
54 |
55 | $.ajax(opts);
56 | }
57 |
58 | function logout(callback) {
59 | $.ajax({
60 | type: 'GET',
61 | url: '/api/token',
62 | username: '--invalid--',
63 | password: '--invalid--',
64 | complete: function() {
65 | if(_history) {
66 | _history.pushState(null, '/');
67 | }
68 | if(typeof callback === 'function') {
69 | callback();
70 | }
71 | }
72 | });
73 | }
74 |
75 | $.ajax({
76 | type: 'GET',
77 | url: '/api/isLoggedIn',
78 | dataType: 'json',
79 | success: function(data) {
80 | if(typeof data === 'object') {
81 | _currentState = !!data.loggedIn;
82 | updateComponents();
83 | }
84 | }
85 | });
86 |
87 | module.exports = {
88 | mixins: [History],
89 |
90 | componentWillMount: function() {
91 | _components.push(this);
92 | if(this.history && !_history) {
93 | _history = this.history;
94 | }
95 | this.setState({ loggedIn: _currentState });
96 | },
97 |
98 | componentWillUnmount: function() {
99 | var index = _components.indexOf(this);
100 | if(index >= 0) {
101 | _components.splice(index, 1);
102 | }
103 | },
104 |
105 | setAuthenticationState: function(loggedIn) {
106 | _currentState = loggedIn;
107 | updateComponents();
108 | },
109 |
110 | doAuthLogin: login,
111 | doAuthLogout: logout
112 | }
113 |
--------------------------------------------------------------------------------
/app/src/questions/10_instructions_to_offerors.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var StateMixin = require("../state_mixin");
3 | var EditBox = require("../edit_box");
4 |
5 | // states data is defined in seeds.py, and must be listed here to be accessed and saved in the database
6 | var STATES = [
7 | "instructionsToOfferors"
8 | ];
9 |
10 | // page_number would be replaced by the number of this page, the data associated with this section would be established in seed.py
11 | var page_number = 10;
12 |
13 | var InstructionsToOfferors= React.createClass({
14 | // include mixins
15 | mixins: [StateMixin],
16 |
17 | // for a state to be accessible with this.state.stateName you must include it here
18 | getInitialState: function() {
19 | // you may also want to establish temporary states for this page that will not be saved
20 | var initialStates = getStates(STATES);
21 | return initialStates;
22 | },
23 | // componentDidMount is where you pull the latest data from the database to populate the states
24 | componentDidMount: function() {
25 | // this identifies the section number identifying the data
26 | var rfqId = getId(window.location.hash);
27 |
28 | // this calls a helpers.js function which calls server.py to access this RFQs data for this section number (XX)
29 | // the names the states are established with in seed.py should correspond to the state names used on this page
30 | get_data(page_number, rfqId, function(content){
31 | var componentStates = getComponents(content["data"]);
32 | console.log(componentStates);
33 | this.setState( componentStates );
34 | }.bind(this));
35 | },
36 | customFuction: function() {
37 | // you can also create functions that will only be used by this page
38 | alert('custom function called!');
39 | },
40 | save: function(cb) {
41 | var data = {};
42 |
43 | // this identifies the section number identifying the data
44 | var rfqId = getId(window.location.hash);
45 |
46 | // get the most recent state data for each STATE that will be saved
47 | for (i=0; i < STATES.length; i++){
48 | var stateName = STATES[i];
49 | data[stateName] = this.state[stateName];
50 | }
51 | console.log(data);
52 | // you can save content_components using the get_content API (the custom_component API is also an option)
53 | put_data(page_number, 'get_content', rfqId, data, cb);
54 |
55 | },
56 | render: function() {
57 | return (
58 |
59 |
Instructions to Offerors
60 |
The content in this section can be decided upon by either the PM or the CO.
61 |
62 |
63 |
64 | );
65 | },
66 | });
67 |
68 |
69 | module.exports = InstructionsToOfferors;
70 |
--------------------------------------------------------------------------------
/app/src/questions/XX_sample.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var StateMixin = require("../state_mixin");
3 | var EditBox = require("../edit_box");
4 |
5 | // states data is defined in seeds.py, and must be listed here to be accessed and saved in the database
6 | var STATES = [
7 | "sampleState1",
8 | "sampleState2",
9 | ];
10 |
11 | // XX would be replaced by the number of this page, the data associated with this section would be established in seed.py
12 | var page_number = 0;
13 |
14 | var Sample= React.createClass({
15 | // include mixins
16 | mixins: [StateMixin],
17 |
18 | // for a state to be accessible with this.state.stateName you must include it here
19 | getInitialState: function() {
20 | // you may also want to establish temporary states for this page that will not be saved
21 | var initialStates = getStates(STATES);
22 | return initialStates;
23 | },
24 | // componentDidMount is where you pull the latest data from the database to populate the states
25 | componentDidMount: function() {
26 | // this identifies the section number identifying the data
27 | var rfqId = getId(window.location.hash);
28 |
29 | // this calls a helpers.js function which calls server.py to access this RFQs data for this section number (XX)
30 | // the names the states are established with in seed.py should correspond to the state names used on this page
31 | get_data(page_number, rfqId, function(content){
32 | var componentStates = getComponents(content["data"]);
33 | this.setState( componentStates );
34 | }.bind(this));
35 | },
36 | customFuction: function() {
37 | // you can also create functions that will only be used by this page
38 | alert('custom function called!');
39 | },
40 | save: function(cb) {
41 | var data = {};
42 |
43 | // this identifies the section number identifying the data
44 | var rfqId = getId(window.location.hash);
45 |
46 | // get the most recent state data for each STATE that will be saved
47 | for (i=0; i < STATES.length; i++){
48 | var stateName = STATES[i];
49 | data[stateName] = this.state[stateName];
50 | }
51 | // you can save content_components using the get_content API (the custom_component API is also an option)
52 | put_data(page_number, 'get_content', rfqId, data, cb);
53 |
54 | },
55 | render: function() {
56 | return (
57 |
58 |
Sample
59 |
The content in this section can be decided upon by either the PM or the CO.
Welcome to the Agile Solicitation Builder, formerly the Playbook in Action! Before you begin, please consider the following:
62 |
63 |
64 |
The intent of this tool is to assist in the creation of requirements documents
65 | for agile software development using best practices from the USDS
66 | Playbook and TechFAR.
67 |
68 |
The PM and the CO should use this tool jointly in partnership. Certain pages will only be applicable to only the CO or the PM.
69 |
70 |
V1 is for firm fixed price contracts only. The firm fixed price will be per iteration.
71 |
This tool is not built to support waterfall development requirements documents.
72 |
73 |
All documents should be approved by a warranted contracting officer and in consultation with your legal counsel as required.
74 |
75 |
Also please note that this product is only in alpha, therefore any of the following may occur:
76 |
77 |
Content may unexpectedly change
78 |
Documents you have created may be deleted without warning
79 |
Certain pages may not always be functioning. We recommend you refresh the page if this happens
The content in this section should be decided on by both the CO and the PM.
46 |
47 |
Overview
48 |
49 |
54 |
55 |
56 |
Delivery & Timing
57 |
58 |
59 |
Government Acceptance
60 |
61 |
66 |
67 |
68 |
69 |
70 |
Notice Regarding Late Delivery
71 |
72 |
77 |
78 |
79 |
80 |
Delivering Deliverables
81 |
The US Digital Service Playbook strongly recommends the use of a version control system such as Github, or similar for storing code and system documentation.
82 |
83 |
88 |
89 |
90 |
91 |
Is your team currently using a collaborative workspace?
92 |
Ex: Sharepoint, JIRA, Rally, Google Drive, Box, etc.
93 |
94 |
107 |
108 |
The contractor will work with the PM and CO to establish a collaborative workspace that is acceptable for both parties.
Address the whole experience, from start to finish
314 |
315 |
320 |
321 |
322 |
323 | : null }
324 |
325 |
326 |
General Requirements
327 |
All agile projects should follow these guidelines.
328 |
329 |
330 |
Build the service using agile and iterative practices
331 |
332 |
337 |
338 |
339 |
340 |
341 |
Make it simple and intuitive
342 |
343 |
348 |
349 |
350 |
351 |
352 |
Use data to drive decisions
353 |
354 |
359 |
360 |
361 |
362 |
Specific Tasks and Deliverables
363 |
364 |
369 |
370 |
371 |
372 |
Which of the following do you anticipate your project will need?
373 |
We have already checked certain components that the USDS Playbook suggests be required for all projects.
374 |
375 |
381 |
382 |
The contractors are required to provide the following services: {deliverablesString}. Each deliverable has been described in more detail below. These functional Requirements will be translated into Epics and User Stories that will be used to populate the Product Backlog.
383 | {selected_deliverables}
384 |
385 |
386 |
Location & Kick-Off Meeting
387 |
388 |
389 |
Will you require the contractor to have a full-time working staff presence onsite at a specific location?
The contractor shall have a full-time working staff presence at {this.state.locationText}. Contractor shall have additional facilities to perform contract functions as necessary.
411 |
:
412 |
The contractor is not required to have a full-time working staff presence on-site.
413 |
414 | }
415 |
416 |
421 |
422 |
423 |
424 |
425 |
Will you require the contractor to attend a kick-off meeting?
465 | //
466 | // to ensure the system supports interoperability, must be followed. (see section). To ensure the user interface is X, Y (playbook language)
467 | module.exports = Objective;
--------------------------------------------------------------------------------