+ // Package on purpose
+ static final String NAME="Approvals";
+ static final String HREF = "/gui/approve";
+ static final String[] FIELDS = new String[] {"line[]","user","delegate_of","as_user"};
+
+
+ public ApprovalForm(final AAF_GUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,NAME,HREF, FIELDS,
+
+ new BreadCrumbs(breadcrumbs),
+ new NamedCode(false, "filterByUser") {
+ @Override
+ public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+ cache.dynamic(hgen, new DynamicCode<HTMLGen, AAF_GUI, AuthzTrans>() {
+ @Override
+ public void code(final AAF_GUI gui, final AuthzTrans trans, final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+ String user = trans.get(trans.env().slot(NAME+".user"),"");
+ hgen.incr("p", "class=userFilter")
+ .text("Filter by User:")
+ .tagOnly("input", "type=text", "value="+user, "id=userTextBox")
+ .tagOnly("input", "type=button", "onclick=userFilter('"+HREF+"');", "value=Go!")
+ .end();
+ }
+ });
+ }
+ },
+ new Form(true,new Table<AAF_GUI,AuthzTrans>("Approval Requests", gui.env.newTransNoAvg(),new Model(gui.env),"class=stdform"))
+ .preamble("The following requires your Approval to proceed in the AAF System.</p><p class=subtext>Hover on Name for Identity; If Deny is the only option, User is no longer valid."),
+ new NamedCode(false, "selectAlljs") {
+ @Override
+ public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+ Mark jsStart = new Mark();
+ hgen.js(jsStart);
+ hgen.text("function selectAll(radioClass) {");
+ hgen.text("var radios = document.querySelectorAll(\".\"+radioClass);");
+ hgen.text("for (i = 0; i < radios.length; i++) {");
+ hgen.text("radios[i].checked = true;");
+ hgen.text("}");
+ hgen.text("}");
+ hgen.end(jsStart);
+ }
+ });
+ }
+
+ /**
+ * Implement the Table Content for Approvals
+ *
+ * @author Jonathan
+ *
+ */
+ private static class Model extends TableData<AAF_GUI,AuthzTrans> {
+ //TODO come up with a generic way to do ILM Info (people page)
+// private static final String TODO_ILM_INFO = "TODO: ILM Info";
+
+
+ private static final String[] headers = new String[] {"Identity","Request","Approve","Deny"};
+ private Slot sUser;
+ private Slot sAsDelegate;
+ private Slot sAsUser;
+
+ public Model(AuthzEnv env) {
+ sUser = env.slot(NAME+".user");
+ sAsDelegate = env.slot(NAME+".delegate_of");
+ sAsUser = env.slot(NAME + ".as_user");
+ }
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthzTrans trans, final AAF_GUI gui) {
+ final String userParam = trans.get(sUser, null);
+
+ final String asDelegate = trans.get(sAsDelegate, null);
+ final String approver;
+ if(asDelegate==null) {
+ approver = trans.get(sAsUser,trans.user());
+ } else {
+ approver = asDelegate;
+ }
+
+ ArrayList<AbsCell[]> rv = new ArrayList<>();
+ String msg = null;
+ TimeTaken tt = trans.start("AAF Get Approvals for Approver",Env.REMOTE);
+ try {
+ final List<Approval> pendingApprovals = new ArrayList<>();
+ final List<Integer> beginIndicesPerApprover = new ArrayList<>();
+ int numLeft = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Integer>() {
+ @Override
+ public Integer code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+ Future<Approvals> fa = client.read("/authz/approval/approver/"+approver,gui.getDF(Approvals.class));
+ int numLeft = 0;
+ if (fa.get(AAF_GUI.TIMEOUT)) {
+
+ if (fa.value!=null) {
+ for (Approval appr : fa.value.getApprovals()) {
+ if ("pending".equals(appr.getStatus())) {
+ if (userParam!=null && !appr.getUser().equalsIgnoreCase(userParam)) {
+ numLeft++;
+ continue;
+ }
+ pendingApprovals.add(appr);
+ }
+ }
+ }
+
+ String prevApprover = null;
+ int overallIndex = 0;
+
+ for (Approval appr : pendingApprovals) {
+ String currApprover = appr.getApprover();
+ if (!currApprover.equals(prevApprover)) {
+ prevApprover = currApprover;
+ beginIndicesPerApprover.add(overallIndex);
+ }
+ overallIndex++;
+ }
+ }
+ return numLeft;
+ }
+ });
+
+ if (!pendingApprovals.isEmpty()) {
+ // Only add select all links if we have approvals
+ AbsCell[] selectAllRow = new AbsCell[] {
+ AbsCell.Null,
+ AbsCell.Null,
+ new ButtonCell("all", "onclick=selectAll('approve')", "class=selectAllButton"),
+ new ButtonCell("all", "onclick=selectAll('deny')", "class=selectAllButton")
+ };
+ rv.add(selectAllRow);
+ }
+
+ int line=-1;
+
+ while (!beginIndicesPerApprover.isEmpty()) {
+ int beginIndex = beginIndicesPerApprover.remove(0);
+ int endIndex = (beginIndicesPerApprover.isEmpty()?pendingApprovals.size():beginIndicesPerApprover.get(0));
+ List<Approval> currApproverList = pendingApprovals.subList(beginIndex, endIndex);
+
+ Identity iapprover = trans.org().getIdentity(trans,currApproverList.get(0).getApprover());
+ if(iapprover==null) {
+ rv.add(new AbsCell[] {
+ new TextCell(currApproverList.get(0).getApprover() + " is not part of Organization",
+ new String[] {"colspan=4", "class=head"})
+ });
+ } else {
+ if (!iapprover.fullID().equals(trans.user())) {
+
+ AbsCell[] approverHeader;
+ // if (domainOfUser.equals(domainOfApprover)) {
+ // approverHeader = new AbsCell[] {
+ // new TextAndRefCell("Approvals Delegated to Me by ", currApproverFull,
+ // TODO_ILM_INFO + currApproverShort,
+ // true,
+ // new String[] {"colspan=4", "class=head"})
+ // };
+ // } else {
+ approverHeader = new AbsCell[] {
+ new TextCell("Approvals Delegated to Me by " + iapprover.fullName()
+ + '(' + iapprover.id() + ')',
+ new String[] {"colspan=4", "class=head"})
+ };
+ // }
+ rv.add(approverHeader);
+ }
+
+ // Sort by User Requesting
+ Collections.sort(currApproverList, new Comparator<Approval>() {
+ @Override
+ public int compare(Approval a1, Approval a2) {
+ return a1.getUser().compareTo(a2.getUser());
+ }
+ });
+
+ String prevUser = null;
+ boolean userOK=true;
+ for (Approval appr : currApproverList) {
+ if (++line<MAX_LINE) { // limit number displayed at one time.
+ AbsCell userCell;
+ String user = appr.getUser();