https://www.zkoss.org/wiki/ZK_Spring_Essentials/Working_with_ZK_Spring/Working_with_ZK_Spring_Security/Secure_a_ZK_Application_with_Spring_Security
https://www.zkoss.org/wiki/ZK_Spring_Essentials/Working_with_ZK_Spring/Working_with_ZK_Spring_Security/Add_Security_in_the_View_Layer
(To enable remove @SpringBootApplication with exludes and @ComponentScan)
+https://www.baeldung.com/get-user-in-spring-security
+https://www.baeldung.com/spring-security-authentication-provider
##### ZK Style
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>hu.user</groupId>
<artifactId>lis-app</artifactId>
- <version>0.1.1-SNAPSHOT</version>
+ <version>0.1.2-SNAPSHOT</version>
<parent>
<groupId>hu.user</groupId>
<artifactId>lis</artifactId>
jpa:
hibernate:
use-new-id-generator-mappings: false
- show-sql: false
+ show-sql: true
properties:
hibernate:
format_sql: true
logging:
level:
org.hibernate.engine.jdbc.spi.SqlExceptionHelper: ERROR
- org.springframework.security.web: DEBUG
+ org.springframework.security: DEBUG
+ org.springframework.security.web: INFO
# pattern:
# console: "%d %-5level %logger : %msg%n"
# file: "%d %-5level [%thread] %logger : %msg%n"
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) $today.year-$today.month-24.
+ * By elGekko
+ */
+
+package hu.user.lis;
+
+import hu.user.lis.ui.data.AssociatesDataModel;
+import lombok.extern.log4j.Log4j2;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.test.context.junit4.SpringRunner;
+
+
+@Log4j2
+@RunWith(SpringRunner.class)
+@ComponentScan("hu.user.lis")
+@SpringBootTest
+//@TestPropertySource("classpath:application.yaml")
+//@AutoConfigureMockMvc
+public class AssociatesDataModelIT {
+ @Autowired
+ private AssociatesDataModel associatesDataModel;
+
+ @Test
+ public void testRepositoryCapabilities() {
+ associatesDataModel.search("lé");
+ log.info("Found {} items", associatesDataModel.getResultSetCount());
+ associatesDataModel.getResultSet(0, 10, null)
+ .forEach(c -> log.info("{}", c.getName()));
+ }
+
+}
@SpringBootTest
//@TestPropertySource("classpath:application.yaml")
//@AutoConfigureMockMvc
-public class ITRepository {
+public class RepositoryIT {
@Autowired
private ServiceRecordRepository serviceRecordRepository;
--- /dev/null
+-- // add_remotely_authenticated_to_associate
+-- Migration SQL that makes the change goes here.
+
+ALTER TABLE associate
+ ADD COLUMN remotely_authenticated SMALLINT NOT NULL DEFAULT 0;
+
+-- //@UNDO
+-- SQL to undo the change goes here.
+
+ALTER TABLE associate
+ DROP COLUMN remotely_authenticated;
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
- <groupId>hu.user</groupId>
<artifactId>lis-db</artifactId>
<parent>
<groupId>hu.user</groupId>
String password;
double monthlyCost;
boolean active;
+ boolean remotelyAuthenticated;
}
import org.springframework.data.jpa.repository.JpaRepository;
public interface AssociateRepository extends JpaRepository<Associate, Long>, AssociateRepositorySearch {
+ Associate findByLoginAndPassword(String login, String password);
+ Associate findByLogin(String login);
}
return predicates.toArray(new Predicate[]{});
}
-// Predicate[] getPredicates(CriteriaBuilder cb, Root<Associate> root, String partialName, boolean filterShowActive) {
-// List<Predicate> predicates = new ArrayList<>();
-// if (StringUtils.isNotBlank(partialName)) {
-// predicates.add(cb.like(root.get("name"), "%" + partialName + "%"));
-// }
-// if (filterShowActive) {
-// predicates.add(cb.isTrue(root.get("active")));
-// } else {
-// predicates.add(cb.isFalse(root.get("active")));
-// }
-// return predicates.toArray(new Predicate[]{});
-// }
-
@Override
public List<Associate> search(String partialName, boolean filterShowActive, boolean filterShowInActive, Pageable pageable) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Associate> cq = cb.createQuery(Associate.class);
Root<Associate> root = cq.from(Associate.class);
- TypedQuery<Associate> query = entityManager.createQuery(cq);
+
cq.where(getPredicates(cb, root, partialName, filterShowActive, filterShowInActive));
+ TypedQuery<Associate> query = entityManager.createQuery(cq);
query.setMaxResults(pageable.getPageSize());
query.setFirstResult(pageable.getPageSize() * pageable.getPageNumber());
return query.getResultList();
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<Associate> root = cq.from(Associate.class);
+
cq.select(cb.count(root));
cq.where(getPredicates(cb, root, partialName, filterShowActive, filterShowInActive));
return entityManager.createQuery(cq).getSingleResult();
}
-// @Override
-// public List<Associate> search(String partialName, boolean filterShowActive, Pageable pageable) {
-// CriteriaBuilder cb = entityManager.getCriteriaBuilder();
-// CriteriaQuery<Associate> cq = cb.createQuery(Associate.class);
-// Root<Associate> root = cq.from(Associate.class);
-// TypedQuery<Associate> query = entityManager.createQuery(cq);
-// cq.where(getPredicates(cb, root, partialName, filterShowActive));
-// query.setMaxResults(pageable.getPageSize());
-// query.setFirstResult(pageable.getPageSize() * pageable.getPageNumber());
-// return query.getResultList();
-// }
-//
-// @Override
-// public long count(String partialName, boolean filterShowActive) {
-// CriteriaBuilder cb = entityManager.getCriteriaBuilder();
-// CriteriaQuery<Long> cq = cb.createQuery(Long.class);
-// Root<Associate> root = cq.from(Associate.class);
-// cq.select(cb.count(root));
-// cq.where(getPredicates(cb, root, partialName, filterShowActive));
-// return entityManager.createQuery(cq).getSingleResult();
-// }
}
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Partner> cq = cb.createQuery(Partner.class);
Root<Partner> root = cq.from(Partner.class);
+
cq.where(getPredicates(cb, root, partialName, partialVatNr, partialAddress, filterShowActive, filterShowInActive));
TypedQuery<Partner> query = entityManager.createQuery(cq);
query.setMaxResults(pageable.getPageSize());
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<Partner> root = cq.from(Partner.class);
+
cq.select(cb.count(root));
cq.where(getPredicates(cb, root, partialName, partialVatNr, partialAddress, filterShowActive, filterShowInActive));
return entityManager.createQuery(cq).getSingleResult();
package hu.user.lis.db.repository;
import hu.user.lis.db.ProjectAssociate;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ProjectAssociateRepository extends JpaRepository<ProjectAssociate, Long> {
+ Page<ProjectAssociate> findAllByProjectId(Long projectId, Pageable pageable);
+
+ Long countByProjectId(Long projectId);
+
}
import java.util.List;
public interface ProjectRepositorySearch {
- List<Project> search(String partialName, boolean filterShowActive, boolean filterShowInActive, Pageable pageable);
+ List<Project> search(String partialSearch, boolean filterShowActive, boolean filterShowInActive, Pageable pageable);
- long count(String partialName, boolean filterShowActive, boolean filterShowInActive);
+ long count(String partialSearch, boolean filterShowActive, boolean filterShowInActive);
}
@PersistenceContext
EntityManager entityManager;
- Predicate[] getPredicates(CriteriaBuilder cb, Root<Project> root, String partialName, boolean filterShowActive, boolean filterShowInActive) {
+ Predicate[] getPredicates(CriteriaBuilder cb, Root<Project> root, String partialSearch, boolean filterShowActive, boolean filterShowInActive) {
List<Predicate> predicates = new ArrayList<>();
- if (StringUtils.isNotBlank(partialName)) {
+ if (StringUtils.isNotBlank(partialSearch)) {
List<Predicate> orPredicates = new ArrayList<>();
- orPredicates.add(cb.like(cb.lower(root.get("name")), "%" + partialName.toLowerCase() + "%"));
- orPredicates.add(cb.like(cb.lower(root.get("humanId")), "%" + partialName.toLowerCase() + "%"));
- orPredicates.add(cb.like(cb.lower(root.join("partner").get("name")), "%" + partialName.toLowerCase() + "%"));
+ orPredicates.add(cb.like(cb.lower(root.get("name")), "%" + partialSearch.toLowerCase() + "%"));
+ orPredicates.add(cb.like(cb.lower(root.get("humanId")), "%" + partialSearch.toLowerCase() + "%"));
+ orPredicates.add(cb.like(cb.lower(root.join("partner").get("name")), "%" + partialSearch.toLowerCase() + "%"));
predicates.add(cb.or(orPredicates.toArray(new Predicate[]{})));
}
}
@Override
- public List<Project> search(String partialName, boolean filterShowActive, boolean filterShowInActive, Pageable pageable) {
+ public List<Project> search(String partialSearch, boolean filterShowActive, boolean filterShowInActive, Pageable pageable) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Project> cq = cb.createQuery(Project.class);
Root<Project> root = cq.from(Project.class);
+
+ cq.where(getPredicates(cb, root, partialSearch, filterShowActive, filterShowInActive));
TypedQuery<Project> query = entityManager.createQuery(cq);
- cq.where(getPredicates(cb, root, partialName, filterShowActive, filterShowInActive));
query.setMaxResults(pageable.getPageSize());
query.setFirstResult(pageable.getPageSize() * pageable.getPageNumber());
return query.getResultList();
}
@Override
- public long count(String partialName, boolean filterShowActive, boolean filterShowInActive) {
+ public long count(String partialSearch, boolean filterShowActive, boolean filterShowInActive) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<Project> root = cq.from(Project.class);
+
cq.select(cb.count(root));
- cq.where(getPredicates(cb, root, partialName, filterShowActive, filterShowInActive));
+ cq.where(getPredicates(cb, root, partialSearch, filterShowActive, filterShowInActive));
return entityManager.createQuery(cq).getSingleResult();
}
}
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<ServiceRecord> cq = cb.createQuery(ServiceRecord.class);
Root<ServiceRecord> root = cq.from(ServiceRecord.class);
+
cq.where(getPredicates(cb, root, filterProjectId, filterAssociateId));
TypedQuery<ServiceRecord> query = entityManager.createQuery(cq);
query.setMaxResults(pageable.getPageSize());
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<ServiceRecord> root = cq.from(ServiceRecord.class);
+
cq.select(cb.count(root));
cq.where(getPredicates(cb, root, filterProjectId, filterAssociateId));
return entityManager.createQuery(cq).getSingleResult();
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>hu.user</groupId>
<artifactId>lis-services</artifactId>
<parent>
<groupId>hu.user</groupId>
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>hu.user</groupId>
<artifactId>lis-ui</artifactId>
<parent>
<groupId>hu.user</groupId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-ldap</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.ldap</groupId>
+ <artifactId>spring-ldap-core</artifactId>
+ </dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
--- /dev/null
+package hu.user.lis.ui.auth;
+
+import hu.user.lis.db.Associate;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.stereotype.Service;
+
+@Service
+@Getter
+@Setter
+public class CurrentProfile {
+
+ private Associate associate;
+
+
+}
--- /dev/null
+package hu.user.lis.ui.auth;
+
+import lombok.extern.log4j.Log4j2;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.zkoss.zk.ui.Executions;
+import org.zkoss.zk.ui.Page;
+import org.zkoss.zk.ui.util.Initiator;
+
+import java.util.Map;
+
+@Log4j2
+public class Guard implements Initiator {
+ @Override
+ public void doInit(Page page, Map<String, Object> args) throws Exception {
+ //HttpServletRequest request = (HttpServletRequest) Executions.getCurrent().getNativeRequest();
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+
+ if (authentication == null || authentication instanceof AnonymousAuthenticationToken) {
+ Executions.sendRedirect("/login");
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package hu.user.lis.ui.auth;
+
+import hu.user.lis.db.Associate;
+import hu.user.lis.db.repository.AssociateRepository;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.ldap.userdetails.LdapUserDetailsImpl;
+import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper;
+import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.Objects;
+
+@Service
+@Log4j2
+public class LdapUserDetailsContextMapper extends LdapUserDetailsMapper implements UserDetailsContextMapper {
+ @Autowired
+ AssociateRepository associateRepository;
+
+ @Autowired
+ CurrentProfile currentProfile;
+
+ @Override
+ public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
+ LdapUserDetailsImpl ldapUserDetailsImpl = (LdapUserDetailsImpl) super.mapUserFromContext(ctx, username, authorities);
+// String dn = ldapDetails.getDn();
+// int beginIndex = dn.indexOf("cn=") + 3;
+// int endIndex = dn.indexOf(",");
+// String username = dn.substring(beginIndex, endIndex);
+// myUserDetails.setAccountNonExpired(ldapUserDetailsImpl.isAccountNonExpired());
+// myUserDetails.setAccountNonLocked(ldapUserDetailsImpl.isAccountNonLocked());
+// myUserDetails.setCredentialsNonExpired(ldapUserDetailsImpl.isCredentialsNonExpired());
+// myUserDetails.setEnabled(ldapUserDetailsImpl.isEnabled());
+// myUserDetails.setAuthorities(ldapUserDetailsImpl.getAuthorities());
+// myUserDetails.setUsername();
+ Associate associate = associateRepository.findByLogin(ldapUserDetailsImpl.getUsername());
+ if (Objects.isNull(associate)) {
+ associate = Associate.builder()
+ .login(ldapUserDetailsImpl.getUsername())
+ .name(ctx.getObjectAttribute("displayname").toString())
+ .active(true)
+ .remotelyAuthenticated(true)
+ .build();
+// ctx.getObjectAttribute("mail")
+ associateRepository.save(associate);
+ }
+ currentProfile.setAssociate(associate);
+ return ldapUserDetailsImpl;
+ }
+}
\ No newline at end of file
--- /dev/null
+package hu.user.lis.ui.auth;
+
+import hu.user.lis.db.Associate;
+import hu.user.lis.db.repository.AssociateRepository;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+@Component
+public class LocalAuthProvider implements AuthenticationProvider {
+ @Autowired
+ AssociateRepository associateRepository;
+
+ @Autowired
+ CurrentProfile currentProfile;
+
+ @Override
+ public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+ UsernamePasswordAuthenticationToken result;
+ String name = authentication.getName();
+ String password = authentication.getCredentials().toString();
+
+ Associate associate = null;
+ if (StringUtils.isNotBlank(password)) {
+ associate = associateRepository.findByLoginAndPassword(name, password);
+ }
+ if (Objects.nonNull(associate)) {
+ result = new UsernamePasswordAuthenticationToken(name, password, Arrays.asList());
+ currentProfile.setAssociate(associate);
+ } else {
+ throw new BadCredentialsException("Local authentication failed!");
+ }
+ return result;
+ }
+
+ @Override
+ public boolean supports(Class<?> authentication) {
+ return authentication.equals(UsernamePasswordAuthenticationToken.class);
+ }
+}
package hu.user.lis.ui.config;
-import org.springframework.context.annotation.Bean;
+import hu.user.lis.ui.auth.LdapUserDetailsContextMapper;
+import hu.user.lis.ui.auth.LocalAuthProvider;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.core.userdetails.User;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import static hu.user.lis.ui.view.IndexViewModel.NAVIGATION;
-/**
- * This is an example of minimal configuration for ZK + Spring Security, we open as less access as possible to run a ZK-based application.
- * Please understand the configuration and modify it upon your requirement.
- */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
public static final String ZUL_FILES = "/zkau/web/**/*.zul";
+
public static final String[] ZK_RESOURCES = {"/zkau/web/**/js/**", "/zkau/web/**/zul/css/**", "/zkau/web/**/img/**"};
+
// allow desktop cleanup after logout or when reloading login page
public static final String REMOVE_DESKTOP_REGEX = "/zkau\\?dtid=.*&cmd_0=rmDesktop&.*";
+ @Autowired
+ LocalAuthProvider localAuthProvider;
+
+ @Autowired
+ LdapUserDetailsContextMapper ldapUserDetailsContextMapper;
@Override
protected void configure(HttpSecurity http) throws Exception {
.regexMatchers(HttpMethod.GET, REMOVE_DESKTOP_REGEX).permitAll() // allow desktop cleanup
.requestMatchers(req -> "rmDesktop".equals(req.getParameter("cmd_0"))).permitAll() // allow desktop cleanup from ZATS
.mvcMatchers("/", "/login", "/logout").permitAll()
- .mvcMatchers(navigation).hasRole("USER")
+ //mvcMatchers(navigation).hasRole("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.logout().logoutUrl("/logout").logoutSuccessUrl("/");
}
- @Bean
- @Override
- public UserDetailsService userDetailsService() {
- UserDetails user =
- User.withDefaultPasswordEncoder()
- .username("user")
- .password("password")
- .roles("USER")
- .build();
-
- return new InMemoryUserDetailsManager(user);
+ @Autowired
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.ldapAuthentication()
+ .userDnPatterns("uid={0},ou=people")
+ .groupSearchBase("ou=groups")
+ .userDetailsContextMapper(ldapUserDetailsContextMapper)
+ .contextSource()
+// .url("ldap://fds.in.useribm.hu:389/dc=user,dc=hu")
+ .url("ldaps://fds.useribm.hu:636/dc=user,dc=hu")
+// .and()
+// .passwordCompare()
+// .passwordEncoder(new BCryptPasswordEncoder())
+// .passwordAttribute("userPassword")
+ ;
+ auth.authenticationProvider(localAuthProvider);
}
}
\ No newline at end of file
private String partialName;
@Override
- protected List<Associate> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+ public List<Associate> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
Pageable pageable = createPageable(0, SEARCH_LIMIT, null);
List<Associate> result = StringUtils.isBlank(partialName) ? associateRepository.findAll(pageable).toList() :
associateRepository.search(partialName, true, false, pageable);
-
- log.info("Associate filter: {}", partialName);
- result.forEach(a -> {
- log.info("Associate: {}", a.getName());
- });
return result;
}
int result = StringUtils.isBlank(partialName) ?
(int) associateRepository.count() :
(int) associateRepository.count(partialName, true, false);
- log.info("Associate filter: {}", partialName);
- log.info("Associate count: {}", result);
return result > SEARCH_LIMIT ? SEARCH_LIMIT : result;
}
private boolean filterShowActive;
@Override
- protected List<Associate> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+ public List<Associate> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
Pageable pageable = createPageable(page, pageSize, sortComparator);
List<Associate> result = listAll ? associateRepository.findAll(pageable).toList() :
associateRepository.search(partialName, filterShowActive, filterShowInActive, pageable);
this.cacheEnd = 0;
clearCache();
- fireEvent(ListDataEvent.STRUCTURE_CHANGED, -1, -1);
- BindUtils.postNotifyChange(null, null, this, "*");
+ try {
+ fireEvent(ListDataEvent.STRUCTURE_CHANGED, -1, -1);
+ BindUtils.postNotifyChange(null, null, this, "*");
+ } catch (Exception e) {
+ log.warn(e.getMessage());
+ }
}
public void clearCache() {
}
}
- abstract protected List<T> getResultSet(int page, int pageSize, FieldComparator sortComparator);
+ abstract public List<T> getResultSet(int page, int pageSize, FieldComparator sortComparator);
abstract public int getResultSetCount();
package hu.user.lis.ui.data;
import hu.user.lis.db.Partner;
-import hu.user.lis.services.data.PartnerService;
+import hu.user.lis.db.repository.PartnerRepository;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
+import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
-import org.zkoss.bind.BindUtils;
import org.zkoss.zul.FieldComparator;
-import java.util.Comparator;
import java.util.List;
-import java.util.stream.Collectors;
@Component
@Log4j2
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
-public class PartnerSelectorDataModel extends CachedDataModel<Partner> {
+public class PartnerSelectorDataModel extends CachedSpringDataModel<Partner> {
static private final int SEARCH_LIMIT = 10;
+
@Autowired
- PartnerService partnerService;
- private String partialName;
+ PartnerRepository partnerRepository;
- private boolean filter(Partner partner) {
- if (StringUtils.isBlank(partialName)) {
- return true;
- } else {
- if (partner.getName().toLowerCase().startsWith(partialName.toLowerCase())) {
- return true;
- }
- }
- return false;
- }
+ private String partialName;
@Override
- protected List<Partner> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
- List<Partner> result = partnerService.getAll().stream()
- .sorted(Comparator.comparing(Partner::getName))
- .filter(s -> filter(s))
- .limit(SEARCH_LIMIT)
- .collect(Collectors.toList());
+ public List<Partner> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+ Pageable pageable = createPageable(page, pageSize, sortComparator);
+ List<Partner> result = StringUtils.isBlank(partialName) ? partnerRepository.findAll() :
+ partnerRepository.search(partialName, partialName, partialName, true, false, pageable);
return result;
}
+
@Override
public int getResultSetCount() {
- int result = (int) partnerService.getAll().stream()
- .filter(s -> filter(s))
- .limit(SEARCH_LIMIT)
- .count();
- return result;
+ int result = StringUtils.isBlank(partialName) ?
+ (int) partnerRepository.count() :
+ (int) partnerRepository.count(partialName, partialName, partialName, true, false);
+ return result > SEARCH_LIMIT ? SEARCH_LIMIT : result;
}
public void search(String partialName) {
log.info("Searching partner using filter {}", partialName);
this.partialName = partialName;
super.reset();
- BindUtils.postNotifyChange(null, null, this, "*");
}
}
public class PartnersDataModel extends CachedSpringDataModel<Partner> {
@Autowired
PartnerRepository partnerRepository;
+
@Autowired
PartnerService partnerService;
+
private String partialName;
+
private String partialAddress;
+
private String partialVatNr;
+
private boolean listAll;
+
private boolean filterShowInActive;
+
private boolean filterShowActive;
@Override
- protected List<Partner> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+ public List<Partner> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
Pageable pageable = createPageable(page, pageSize, sortComparator);
List<Partner> result = listAll ? partnerRepository.findAll() :
partnerRepository.search(partialName, partialVatNr, partialAddress, filterShowActive, filterShowInActive, pageable);
package hu.user.lis.ui.data;
import hu.user.lis.db.ProjectAssociate;
+import hu.user.lis.db.repository.ProjectAssociateRepository;
import hu.user.lis.services.data.ProjectAssociateService;
-import lombok.Getter;
import lombok.extern.log4j.Log4j2;
-import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
+import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
-import org.zkoss.bind.BindUtils;
import org.zkoss.zul.FieldComparator;
import java.util.List;
-import java.util.stream.Collectors;
@Component
@Log4j2
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
-public class ProjectAssociatesDataModel extends CachedDataModel<ProjectAssociate> {
- @Getter
+public class ProjectAssociatesDataModel extends CachedSpringDataModel<ProjectAssociate> {
+
+ @Autowired
+ ProjectAssociateRepository projectAssociateRepository;
+
@Autowired
ProjectAssociateService projectAssociateService;
- private String projectId;
+ private Long projectId;
- private boolean canExecuteSearch() {
- boolean result = StringUtils.isNotBlank(projectId);
- log.info("Can execute search: {}", result);
- return result;
- }
-
- private boolean filter(ProjectAssociate projectAssociate) {
- boolean result = true;
- if (StringUtils.isNotBlank(projectId)) {
- if (!projectAssociate.getProject().getId().equals(projectId)) {
- result = false;
- }
- }
- return result;
- }
@Override
- protected List<ProjectAssociate> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
- List<ProjectAssociate> result = null;
- if (canExecuteSearch()) {
- result = projectAssociateService.getAll().stream()
- .filter(s -> filter(s))
- .collect(Collectors.toList());
- }
+ public List<ProjectAssociate> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+ Pageable pageable = createPageable(page, pageSize, sortComparator);
+ List<ProjectAssociate> result = projectAssociateRepository.findAllByProjectId(projectId, pageable).getContent();
return result;
}
@Override
public int getResultSetCount() {
- int result = 0;
- if (canExecuteSearch()) {
- result = (int) projectAssociateService.getAll().stream()
- .filter(s -> filter(s))
- .count();
- }
- return result;
+ long result = projectAssociateRepository.countByProjectId(projectId);
+ return (int) result;
}
- public void search(String projectId) {
- log.info("Searching project associate using filters: projectId LIKE {}", projectId);
+ public void search(Long projectId) {
+ log.info("Searching project associate using filter: projectId LIKE {}", projectId);
this.projectId = projectId;
super.reset();
- BindUtils.postNotifyChange(null, null, this, "*");
}
}
private String partialSearch;
@Override
- protected List<Project> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+ public List<Project> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
Pageable pageable = createPageable(0, SEARCH_LIMIT, null);
List<Project> result = StringUtils.isBlank(partialSearch) ? projectRepository.findAll(pageable).toList() :
projectRepository.search(partialSearch, true, false, pageable);
private boolean activeOnly;
@Override
- protected List<ProjectStatus> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+ public List<ProjectStatus> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
List<ProjectStatus> result;
if (activeOnly) {
result = projectStatusRepository.findByActiveIsTrue(Sort.by(Sort.Direction.ASC, "order"));
}
public void moveUp(ProjectStatus entity) {
- projectStatusService.getAll().stream().anyMatch(s -> {
+ projectStatusRepository.findAll(Sort.by(Sort.Direction.ASC, "order")).stream().anyMatch(s -> {
if (s.getOrder() == entity.getOrder() + 1) {
s.setOrder(s.getOrder() - 1);
+ projectStatusRepository.save(s);
entity.setOrder(entity.getOrder() + 1);
+ projectStatusRepository.save(entity);
return true;
}
return false;
}
public void moveDown(ProjectStatus entity) {
- projectStatusService.getAll().stream().anyMatch(s -> {
+ projectStatusRepository.findAll(Sort.by(Sort.Direction.ASC, "order")).stream().anyMatch(s -> {
if (s.getOrder() == entity.getOrder() - 1) {
s.setOrder(s.getOrder() + 1);
+ projectStatusRepository.save(s);
entity.setOrder(entity.getOrder() - 1);
+ projectStatusRepository.save(entity);
return true;
}
return false;
entity.setOrder((int) currentCount + 1);
projectStatusRepository.save(entity);
}
+
+ public void save(ProjectStatus entity) {
+ projectStatusRepository.save(entity);
+ }
}
package hu.user.lis.ui.data;
import hu.user.lis.db.Project;
+import hu.user.lis.db.repository.ProjectRepository;
import hu.user.lis.services.data.ProjectService;
-import lombok.Getter;
import lombok.extern.log4j.Log4j2;
-import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
+import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
-import org.zkoss.bind.BindUtils;
import org.zkoss.zul.FieldComparator;
-import java.util.Comparator;
import java.util.List;
-import java.util.stream.Collectors;
@Component
@Log4j2
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
-public class ProjectsDataModel extends CachedDataModel<Project> {
- @Getter
+public class ProjectsDataModel extends CachedSpringDataModel<Project> {
+ @Autowired
+ ProjectRepository projectRepository;
+
@Autowired
ProjectService projectService;
+
private String partialName;
- private String partialHumanId;
- private boolean listAll;
- private boolean filterShowInActive;
- private boolean filterShowActive;
+ private boolean listAll;
- private boolean canExecuteSearch() {
- boolean result = listAll || filterShowActive || filterShowInActive ||
- StringUtils.isNotBlank(partialName) ||
- StringUtils.isNotBlank(partialHumanId);
- log.info("Can execute search: {}", result);
- return result;
- }
+ private boolean filterShowInActive;
- private boolean filter(Project entity) {
- if (listAll) {
- return true;
- }
- boolean result = true;
- if (StringUtils.isNotBlank(partialName)) {
- if (!entity.getName().toLowerCase().startsWith(partialName.toLowerCase())) {
- result = false;
- }
- }
- if (StringUtils.isNotBlank(partialHumanId)) {
- if (!entity.getHumanId().toLowerCase().startsWith(partialHumanId.toLowerCase())) {
- result = false;
- }
- }
- if (!filterShowActive && entity.isActive()) {
- result = false;
- }
- if (!filterShowInActive && !entity.isActive()) {
- result = false;
- }
- return result;
- }
+ private boolean filterShowActive;
@Override
- protected List<Project> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
- List<Project> result = null;
- if (canExecuteSearch()) {
- result = projectService.getAll().stream()
- .filter(s -> filter(s))
- .sorted(Comparator.comparing(Project::getName, String.CASE_INSENSITIVE_ORDER))
- .collect(Collectors.toList());
- }
+ public List<Project> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+ Pageable pageable = createPageable(page, pageSize, sortComparator);
+ List<Project> result = listAll ? projectRepository.findAll() :
+ projectRepository.search(partialName, filterShowActive, filterShowInActive, pageable);
return result;
}
@Override
public int getResultSetCount() {
- int result = 0;
- if (canExecuteSearch()) {
- result = (int) projectService.getAll().stream()
- .filter(s -> filter(s))
- .count();
- }
- return result;
+ long result = listAll ? projectRepository.count() :
+ projectRepository.count(partialName, filterShowActive, filterShowInActive);
+ return (int) result;
}
- public void search(String partialName, String partialHumanId) {
- log.info("Searching partner using filters: name LIKE {}, VAT human ID LIKE {}",
- partialName, partialHumanId);
+ public void search(String partialName) {
+ log.info("Searching partner using filters: name LIKE {}");
listAll = false;
this.partialName = partialName;
- this.partialHumanId = partialHumanId;
super.reset();
- BindUtils.postNotifyChange(null, null, this, "*");
}
this.filterShowInActive = filterShowInActive;
listAll = false;
super.reset();
- BindUtils.postNotifyChange(null, null, this, "*");
}
public void listAll() {
log.info("List all projects");
listAll = true;
super.reset();
- BindUtils.postNotifyChange(null, null, this, "*");
+ }
+
+ public Project createNew() {
+ return projectService.createNew();
+ }
+
+ public void addNew(Project entity) {
+ projectRepository.save(entity);
+ }
+
+ public Project copy(Project selectedEntity) {
+ return projectService.copy(selectedEntity);
+ }
+
+ public Project save(Project selectedEntity) {
+ return projectRepository.save(selectedEntity);
}
}
}
@Override
- protected List<ServiceRecord> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+ public List<ServiceRecord> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
Pageable pageable = createPageable(page, pageSize, sortComparator);
List<ServiceRecord> result = listAll ? serviceRecordRepository.findAll(pageable).toList() :
serviceRecordRepository.search(filterProjectId, filterAssociateId, pageable);
}
@Override
- protected List<Supplier> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+ public List<Supplier> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
List<Supplier> result = null;
if (canExecuteSearch()) {
result = supplierService.getAll().stream()
}
@Override
- protected List<Supplier> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+ public List<Supplier> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
List<Supplier> result = supplierService.getAll().stream()
.sorted(Comparator.comparing(Supplier::getName))
.filter(s -> filter(s))
}
if (StringUtils.isBlank(newData.getName()) ||
StringUtils.isBlank(newData.getLogin()) ||
- StringUtils.isBlank(newData.getPassword()) ||
+ (!newData.isRemotelyAuthenticated() && StringUtils.isBlank(newData.getPassword())) ||
newData.getMonthlyCost() < 1
) {
log.info("Document is not valid");
import com.google.common.collect.ImmutableMap;
import hu.user.lis.ui.Constants;
+import hu.user.lis.ui.auth.CurrentProfile;
import hu.user.lis.ui.event.EventBus;
import hu.user.lis.ui.session.SessionSettings;
import lombok.Getter;
SessionSettings sessionSettings;
@WireVariable
EventBus eventBus;
+
+ @WireVariable
+ CurrentProfile currentProfile;
+
String searchPhrase;
+
String page;
@Init
//project editor
route(path);
+// Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+// if (authentication != null && !(authentication instanceof AnonymousAuthenticationToken)) {
+// }
log.info("Init {}", path);
}
@Init
public void init() {
setFilterShowActive(true);
- Clients.evalJavaScript("pushNav('/')");
+ Clients.evalJavaScript("pushNav('/partners')");
log.info("Initialized");
}
editorWindow.addEventListener("onClose", e -> {
if (e.getData() != null) {
log.info("Partner popup result {}", e.getData());
- partnersDataModel.add(newEntity);
+ partnersDataModel.addNew(newEntity);
partnersDataModel.clearSelection();
refresh();
partnersDataModel.addToSelection(newEntity);
@Command
public void onAdd() {
- Project newEntity = projectsDataModel.getProjectService().createNew();
+ Project newEntity = projectsDataModel.createNew();
// eventBus.showProjectEditor(ImmutableMap.of("formDocument", newEntity));
eventBus.showProjectEditor(null);
}
Project formDocument = args.get("formDocument");
if (args.containsKey("origDocument")) {
Project origDocument = args.get("origDocument");
- projectsDataModel.getProjectService().replace(origDocument, formDocument);
+ projectsDataModel.save(formDocument);
} else {
- projectsDataModel.getProjectService().add(formDocument);
+ projectsDataModel.addNew(formDocument);
}
refresh();
projectsDataModel.addToSelection(formDocument);
editorWindow.addEventListener("onClose", e -> {
if (e.getData() != null) {
log.info("Partner popup result {}", e.getData());
- serviceRecordsDataModel.add(newEntity);
+ serviceRecordsDataModel.addNew(newEntity);
serviceRecordsDataModel.clearSelection();
refresh();
serviceRecordsDataModel.addToSelection(newEntity);
package hu.user.lis.ui.view;
-import com.fasterxml.jackson.core.JsonProcessingException;
import hu.user.lis.db.ProjectStatus;
import hu.user.lis.ui.data.ProjectStatusDataModel;
import lombok.Getter;
-import lombok.Setter;
import lombok.extern.log4j.Log4j2;
+import org.zkoss.bind.BindContext;
import org.zkoss.bind.annotation.Command;
+import org.zkoss.bind.annotation.ContextParam;
+import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.Init;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.WireVariable;
@Getter
ProjectStatusDataModel projectStatusDataModel;
@Getter
- @Setter
private ProjectStatus selectedProjectStatus;
@Init
}
@Command
- public void onAppend() throws JsonProcessingException {
+ public void onAppend() {
projectStatusDataModel.append();
projectStatusDataModel.listAll();
}
+ @Command
+ public void onActiveChecked(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) {
+// CheckEvent evt = (CheckEvent) ctx.getTriggerEvent();
+// ProjectStatus entity = (ProjectStatus) evt.getData();
+// projectStatusDataModel.save(entity);
+ }
+ public void setSelectedProjectStatus(ProjectStatus selectedProjectStatus) {
+ log.info("Sekected {}", selectedProjectStatus.getName());
+ this.selectedProjectStatus = selectedProjectStatus;
+ }
}
<session-timeout>300</session-timeout>
<timeout-uri>/timeout</timeout-uri>
</session-config>
+ <!-- <error-page>-->
+ <!-- <exception-type>java.lang.Throwable</exception-type>-->
+ <!-- <location>/timeout</location>-->
+ <!-- </error-page>-->
<!-- <system-config>-->
<!-- <ui-factory-class>org.zkoss.zk.ui.http.SerializableUiFactory</ui-factory-class>-->
<!-- <max-upload-size>10240</max-upload-size>-->
<label value="Jelszó"/>
<hlayout>
<textbox hflex="true" instant="true" type="password"
+ disabled="@load(vm.formDocument.remotelyAuthenticated)"
value="@bind(vm.formDocument.password) @validator(vm)"
forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
<button iconSclass="z-icon-eye"/>
+<?init class="hu.user.lis.ui.auth.Guard"?>
<?link rel="stylesheet" type="text/css" href="~./static/css/skeleton.css" ?>
<?link rel="stylesheet" type="text/css" href="~./static/css/webclient.css" ?>
<zk>
<style>
+ <!-- .z-caption-content {-->
+ <!-- width: 100%;-->
+ <!-- }-->
.z-window-header {
font-size: 18px;
font-weight: bolder;
</script>
<window vflex="true" viewModel="@id('vm') @init('hu.user.lis.ui.view.IndexViewModel')">
<caption>
- <hlayout valign="middle">
- <image width="24px" height="24px" src="~./static/images/logo.png"/>
- <label value="SLY-CRM"/>
- <separator orient="vertical"/>
- <label style="font-size: 0.8em" value="@load(vm.buildProperties.version)"/>
- </hlayout>
+ <div style="display: block">
+ <div style="display: inline; float: left">
+ <hlayout valign="middle">
+ <image width="24px" height="24px" src="~./static/images/logo.png"/>
+ <label value="SLY-CRM"/>
+ <separator orient="vertical"/>
+ <label style="font-size: 0.8em" value="@load(vm.buildProperties.version)"/>
+ </hlayout>
+ </div>
+ <div style="display: inline; float: right">
+ <hlayout valign="middle">
+ <menubar autodrop="true" hflex="true">
+ <menu iconSclass="z-icon-user" label="@load(vm.currentProfile.associate.name)">
+ <menupopup>
+ <menuitem iconSclass="z-icon-user" label="Profil">
+ <attribute name="onClick"><![CDATA[
+ Messagebox.show("Coming soon!", "Information", Messagebox.OK, Messagebox.INFORMATION);
+ ]]></attribute>
+ </menuitem>
+ <menuseparator/>
+ <menuitem label="Kijelentkezés">
+ <attribute name="onClick"><![CDATA[
+ Executions.sendRedirect("/logout");
+ ]]></attribute>
+ </menuitem>
+ </menupopup>
+ </menu>
+ </menubar>
+ <!-- <button iconSclass="z-icon-user"-->
+ <!-- label="@load(vm.currentProfile.associate.name)"/>-->
+ </hlayout>
+ </div>
+
+ </div>
</caption>
+
<borderlayout>
<north border="none" hflex="true">
- <hlayout valign="middle">
- <menubar autodrop="true" hflex="true">
- <menuitem iconSclass="z-icon-group" label="Partnerek"
- onClick="@command(vm.selectPage('~./partners.zul'))"/>
- <menuitem iconSclass="z-icon-tasks" label="Projektek"
- onClick="@command(vm.selectPage('~./projects.zul'))"/>
- <menuitem iconSclass="z-icon-th" label="Munkalapok"
- onClick="@command(vm.selectPage('~./service-records.zul'))"/>
- <menuseparator/>
- <menuitem iconSclass="z-icon-user" label="Munkatársak"
- onClick="@command(vm.selectPage('~./associates.zul'))"/>
- <menuseparator/>
- <menuitem iconSclass="z-icon-cogs" label="Beállítások"
- onClick="@command(vm.selectPage('~./settings.zul'))"/>
- </menubar>
- <hbox hflex="min" pack="right">
- <textbox value="@bind(vm.searchPhrase)" onOK="@command('search')" disabled="true"></textbox>
- <button iconSclass="z-icon-search"/>
- </hbox>
- </hlayout>
+ <vlayout>
+ <hlayout valign="middle">
+ <menubar autodrop="true" hflex="true">
+ <menuitem iconSclass="z-icon-group" label="Partnerek"
+ onClick="@command(vm.selectPage('~./partners.zul'))"/>
+ <menuitem iconSclass="z-icon-tasks" label="Projektek"
+ onClick="@command(vm.selectPage('~./projects.zul'))"/>
+ <menuitem iconSclass="z-icon-th" label="Munkalapok"
+ onClick="@command(vm.selectPage('~./service-records.zul'))"/>
+ <menuseparator/>
+ <menuitem iconSclass="z-icon-user" label="Munkatársak"
+ onClick="@command(vm.selectPage('~./associates.zul'))"/>
+ <menuseparator/>
+ <menuitem iconSclass="z-icon-cogs" label="Beállítások"
+ onClick="@command(vm.selectPage('~./settings.zul'))"/>
+ </menubar>
+ <hbox hflex="min" pack="right">
+ <textbox value="@bind(vm.searchPhrase)" onOK="@command('search')" disabled="true"></textbox>
+ <button iconSclass="z-icon-search"/>
+ </hbox>
+ </hlayout>
+ </vlayout>
</north>
<center border="none" hflex="true">
<include src="@load(vm.page)" hflex="true" vflex="true"/>
-
- <!-- <tabbox id="mainContent" vflex="true" hflex="true" orient="top" selectedIndex="@bind(vm.selectedPage)">-->
- <!-- <tabs visible="true">-->
- <!-- <tab id="tab0" label="Partnerek"/>-->
- <!-- <tab id="tab1" label="Projektek"/>-->
- <!-- <tab id="tab2" label="Szerkesztő"/>-->
- <!-- </tabs>-->
- <!-- <tabpanels>-->
- <!-- <tabpanel id="partnersTab">-->
- <!-- <partners/>-->
- <!-- </tabpanel>-->
- <!-- <tabpanel id="projectsTab"-->
- <!-- fulfill="self.linkedTab.onSelect, projectsMenuItem.onClick, onFulFillProjectsTab">-->
- <!-- <projects/>-->
- <!-- </tabpanel>-->
- <!-- <tabpanel id="editorTab">-->
- <!-- <include src="@load(vm.editor)" hflex="true" vflex="true"/>-->
- <!-- </tabpanel>-->
- <!-- </tabpanels>-->
- <!-- </tabbox>-->
</center>
</borderlayout>
</window>
-<!--<zk>-->
-<!-- <window title="login">-->
-<!-- <label value="AAAAAAAAA"/>-->
-
-<!-- </window>-->
-
-<!--</zk>-->
<zk xmlns:n="native">
+ <n:style>
+ body, html {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ display:table;
+ }
+ body {
+ display:table-cell;
+ vertical-align:middle;
+ }
+ form {
+ display:table;
+ margin:auto;
+ }
+ </n:style>
<n:form action="/login" method="POST">
- <grid width="450px">
+ <grid style="margin-top: 200px">
<columns>
- <column width="160px"/>
+ <column width="100px"/>
<column width="280px"/>
</columns>
<rows>
<row spans="2" align="center">
- <label value="LOGIN"/>
+ <hlayout valign="middle">
+ <!-- <image width="24px" height="24px" src="~./static/images/logo.png"/>-->
+ <label value="SLY-CRM bejelentkezés"/>
+ </hlayout>
</row>
<row>
- <label value="User :"/>
+ <label value="User"/>
<textbox name="username" value="user"/>
</row>
<row>
- <label value="Password :"/>
+ <label value="Password"/>
<textbox type="password" name="password" value="password"/>
</row>
<row spans="2" align="right">
<hlayout>
- <button type="reset" label="Reset"/>
- <button type="submit" label="Login"/>
+ <button type="reset" label="Mégsem"/>
+ <button type="submit" label="Belépés"/>
</hlayout>
</row>
</rows>
<textbox inplace="true" instant="true" width="100%" value="@bind(each.name)"/>
</listcell>
<listcell>
- <checkbox checked="@bind(each.active)"/>
+ <checkbox checked="@bind(each.active)" onCheck="@command('onActiveChecked')"/>
</listcell>
</listitem>
</template>