<?xml version="1.0" encoding="UTF-8" ?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at
  
      http://www.apache.org/licenses/LICENSE-2.0
    	  
  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied.  See the License for the
  specific language governing permissions and limitations
  under the License.
  
-->
<library>
	
<!--- Existing organization list. used by orgAdmin only -->
<class name="ldapAdminListItem" extends="baseContentListItem">
    
    <attribute name="ldapConfigId" value="0" type="number" />
    <attribute name="tName" value="" type="string" />
    <attribute name="configFileName" value="" type="string" />
    
    <turnOverTextItem text="$once{ parent.ldapConfigId }" width="120" />
    <turnOverTextItem text="$once{ parent.tName }" width="200" />
    <turnOverTextItem text="$once{ parent.configFileName }" width="200" />
    
</class>	

<!--- Organization administration module for ADMIN.-->
<class name="ldapAdmin" extends="baseContentView">
	
	<turnOverList name="_turnoverlist" width="420" 
		height="${ canvas.height - canvas.naviHeight }" x="2" 
		y="${ 0 - parent.parent.parent.y }" 
		orderby="ldapConfigId" step="50" asc="true">

		<handler name="oninit">
			this.addHeaderItem(1104,60);
			this.addHeaderItem(1105,184);
			this.addHeaderItem(1106,160);
			this.getLdapConfigs.doCall();
		</handler>
		
		<handler name="oncallnext" >
			this.getLdapConfigs.doCall();
		</handler>
		
		<handler name="oncallpre" >		
			this.getLdapConfigs.doCall();
		</handler>
		
		<handler name="onclickedItem" args="obj">
			//Debug.write("onclickedItem",obj,obj.obj);
			parent._ldapAdminValueForm.initValueFieldsByObject(obj.obj);
		</handler>
		
		<netRemoteCallHib name="getLdapConfigs" funcname="ldapconfigservice.getLdapConfigs" remotecontext="$once{ canvas.thishib }" >      
			<netparam><method name="getValue"> return canvas.sessionId; </method></netparam>
			<netparam><method name="getValue"> return parent.parent.start; </method></netparam>
			<netparam><method name="getValue"> return parent.parent.step; </method></netparam>
			<netparam><method name="getValue"> return parent.parent.orderby; </method></netparam>
			<netparam><method name="getValue"> return parent.parent.asc; </method></netparam>
	    	<handler name="ondata" args="value">
	    		if ($debug) Debug.write("getLdapConfigs ",value);
	    		//this.parent.destroy();
	    		this.parent.initValues(value.records);
	    		this.parent.renderContent(value.result);
	    	</handler>
	    </netRemoteCallHib>	
	    
	    <method name="renderContent" args="records">
	    	<![CDATA[
	    	this.clearList();
	    	for (var i=0;i<records.length;i++){
	    		new lz.ldapAdminListItem(this._innerlist._inn._inn,{
    	    		                 obj:records[i],
    	    		                 ldapConfigId:records[i].ldapConfigId,
    	    		                 tName:records[i].name,
    	    		                 configFileName:records[i].configFileName
	    		                 });
	    	}
            this.sendInitialWidthUpdate();
	    	]]>
	    </method>

	</turnOverList>
	
	<ldapAdminValueForm name="_ldapAdminValueForm" x="440">
        <handler name="onnew" args="refObj">
            parent._turnoverlist.clearSelection();
        </handler>
    </ldapAdminValueForm>
	 
</class>

</library>
