xbase patch_20230608 추가
parent
f0942e2a88
commit
9e64ca6a3f
@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cokr.xit.base.security.access.dao.ActionGroupMapper">
|
||||
|
||||
<resultMap id="groupRow" type="cokr.xit.base.security.access.ActionGroup">
|
||||
<result property="id" column="GRP_ID"/>
|
||||
<result property="name" column="GRP_NM"/>
|
||||
<result property="description" column="DSCRP"/>
|
||||
<result property="createdAt" column="REG_DT"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectGroups"><include refid="utility.paging-prefix" />
|
||||
SELECT A.*
|
||||
FROM TB_ACTION_GRP A
|
||||
<where>
|
||||
<if test="groupIDs != null">AND GRP_ID IN (<foreach collection="groupIDs" item="groupID" separator=",">#{groupID}</foreach>)</if>
|
||||
<if test="by != null and term != null">AND ${by} LIKE CONCAT('%', #{term}, '%')</if>
|
||||
</where>
|
||||
<include refid="utility.paging-suffix" /></sql>
|
||||
|
||||
<select id="getGroupList" parameterType="map" resultType="dataobject">/* 기능그룹 목록 조회(actionGroupMapper.getGroupList) */
|
||||
<include refid="selectGroups" /></select>
|
||||
|
||||
<select id="getGroups" parameterType="map" resultMap="groupRow">/* 기능그룹 가져오기(actionGroupMapper.getGroups) */
|
||||
<include refid="selectGroups" /></select>
|
||||
|
||||
<insert id="insertGroup" parameterType="cokr.xit.base.security.access.ActionGroup">/* 기능그룹 등록(actionGroupMapper.insertGroup) */
|
||||
INSERT INTO TB_ACTION_GRP (
|
||||
GRP_ID
|
||||
, GRP_NM
|
||||
, DSCRP
|
||||
, REG_DT
|
||||
) VALUES (
|
||||
#{id}
|
||||
, #{name}
|
||||
, #{description}
|
||||
,<include refid="utility.now" />
|
||||
)</insert>
|
||||
|
||||
<update id="updateGroup" parameterType="cokr.xit.base.security.access.ActionGroup">/* 기능그룹 수정(actionGroupMapper.updateGroup) */
|
||||
UPDATE TB_ACTION_GRP SET
|
||||
GRP_NM = #{name}
|
||||
, DSCRP = #{description}
|
||||
WHERE GRP_ID = #{id}</update>
|
||||
|
||||
<delete id="removeGroups" parameterType="map">/* 기능그룹 삭제(actionGroupMapper.removeGroups) */
|
||||
DELETE FROM TB_ACTION_GRP
|
||||
WHERE GRP_ID IN (<foreach collection="groupIDs" item="groupID" separator=",">#{groupID}</foreach>)</delete>
|
||||
|
||||
<select id="getActionList" parameterType="map" resultType="dataobject">/* 그룹별 기능 가져오기(actionGroupMapper.getActionList) */
|
||||
SELECT *
|
||||
FROM TB_GRP_ACTION
|
||||
<if test="groupIDs != null">WHERE GRP_ID IN (<foreach collection="groupIDs" item="groupID" separator=",">#{groupID}</foreach>)</if>
|
||||
ORDER BY GRP_ID, ACTION
|
||||
</select>
|
||||
|
||||
<insert id="addActions" parameterType="map">/* 그룹별 기능 추가(actionGroupMapper.addActions) */
|
||||
INSERT INTO TB_GRP_ACTION (GRP_ID, ACTION, REG_DT, RGTR)
|
||||
SELECT GRP_ID, ACTION,<include refid="utility.now" />, #{currentUser.id}
|
||||
FROM (<foreach collection="actions" item="action" separator="UNION">
|
||||
SELECT #{groupID} GRP_ID, #{action} ACTION FROM DUAL</foreach>
|
||||
) A
|
||||
WHERE NOT EXISTS (
|
||||
SELECT GRP_ID, ACTION
|
||||
FROM TB_GRP_ACTION B
|
||||
WHERE B.GRP_ID = A.GRP_ID
|
||||
AND B.ACTION = A.ACTION
|
||||
)</insert>
|
||||
|
||||
<delete id="removeActions" parameterType="map">/* 그룹별 기능 삭제(actionGroupMapper.removeActions) */
|
||||
DELETE FROM TB_GRP_ACTION
|
||||
<where>
|
||||
<if test="groupIDs != null">AND GRP_ID IN (<foreach collection="groupIDs" item="groupID" separator=",">#{groupID}</foreach>)</if>
|
||||
<if test="actions != null">AND ACTION IN (<foreach collection="actions" item="action" separator=",">#{action}</foreach>)</if>
|
||||
</where>
|
||||
</delete>
|
||||
|
||||
</mapper>
|
@ -0,0 +1,141 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cokr.xit.base.security.access.dao.AuthorityMapper">
|
||||
|
||||
<resultMap id="authRow" type="cokr.xit.base.security.Authority">
|
||||
<result property="type" column="AUTH_TYPE"/>
|
||||
<result property="id" column="AUTH_ID"/>
|
||||
<result property="name" column="AUTH_NM"/>
|
||||
<result property="infoScope" column="INF_SCP"/>
|
||||
<result property="userInfoScope" column="USER_INF_SCP"/>
|
||||
<result property="description" column="DSCRP"/>
|
||||
<result property="createdAt" column="REG_DT"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectAuthorities"><include refid="utility.paging-prefix" />
|
||||
SELECT * FROM (
|
||||
SELECT 0 AUTH_TYPE, 'ROLE_ADMIN' AUTH_ID, '시스템 관리자' AUTH_NM, '시스템 관리자' DSCRP, 'all' INF_SCP, 'all' USER_INF_SCP,<include refid="utility.now"/>REG_DT UNION
|
||||
SELECT 1 AUTH_TYPE, 'ROLE_ANONYMOUS' AUTH_ID, '익명 사용자' AUTH_NM, '모든 사용자' DSCRP, 'none' INF_SCP, 'none' USER_INF_SCP,<include refid="utility.now"/>REG_DT UNION
|
||||
SELECT 1 AUTH_TYPE, 'ROLE_USER' AUTH_ID, '시스템 사용자' AUTH_NM, '로그인한 사용자' DSCRP, 'self' INF_SCP, 'self' USER_INF_SCP,<include refid="utility.now"/>REG_DT UNION
|
||||
SELECT 2 AUTH_TYPE, AUTH_ID, AUTH_NM, DSCRP, INF_SCP, USER_INF_SCP, REG_DT
|
||||
FROM TB_AUTHORITY
|
||||
) A
|
||||
<where>
|
||||
<if test="authIDs != null">AND AUTH_ID IN (<foreach collection="authIDs" item="authID" separator=",">#{authID}</foreach>)</if>
|
||||
<if test="by != null and term != null">AND ${by} LIKE CONCAT('%', #{term}, '%')</if>
|
||||
</where>
|
||||
<include refid="utility.orderBy"/>
|
||||
<include refid="utility.paging-suffix" /></sql>
|
||||
|
||||
<select id="getAuthorityList" parameterType="map" resultType="dataobject">/* 권한 목록 조회(authorityMapper.getAuthorityList) */
|
||||
<include refid="selectAuthorities" /></select>
|
||||
|
||||
<select id="getAuthorities" parameterType="map" resultMap="authRow">/* 권한 가져오기(authorityMapper.getAuthorities) */
|
||||
<include refid="selectAuthorities" /></select>
|
||||
|
||||
<insert id="insertAuthority" parameterType="cokr.xit.base.security.Authority">/* 권한 등록(authorityMapper.insertAuthority) */
|
||||
INSERT INTO TB_AUTHORITY (
|
||||
AUTH_ID
|
||||
, AUTH_NM
|
||||
, DSCRP
|
||||
, INF_SCP
|
||||
, USER_INF_SCP
|
||||
, REG_DT
|
||||
) VALUES (
|
||||
#{id}
|
||||
, #{name}
|
||||
, #{description}
|
||||
, #{infoScope}
|
||||
, #{userInfoScope}
|
||||
,<include refid="utility.now" />
|
||||
)</insert>
|
||||
|
||||
<update id="updateAuthority" parameterType="cokr.xit.base.security.Authority">/* 권한 수정(authorityMapper.updateAuthority) */
|
||||
UPDATE TB_AUTHORITY SET
|
||||
AUTH_NM = #{name}
|
||||
, DSCRP = #{description}
|
||||
, INF_SCP = #{infoScope}
|
||||
, USER_INF_SCP = #{userInfoScope}
|
||||
WHERE AUTH_ID = #{id}</update>
|
||||
|
||||
<delete id="removeAuthorities" parameterType="map">/* 권한 삭제(authorityMapper.removeAuthorities) */
|
||||
DELETE FROM TB_AUTHORITY
|
||||
WHERE AUTH_ID IN (<foreach collection="authIDs" item="authID" separator=",">#{authID}</foreach>)</delete>
|
||||
|
||||
<select id="getActionGroupList" parameterType="map" resultType="dataobject">/* 권한-기능그룹 가져오기(authorityMapper.getActionGroups) */
|
||||
<include refid="utility.paging-prefix" />
|
||||
SELECT *
|
||||
FROM TB_AUTH_ACTION
|
||||
<if test="authIDs != null">WHERE AUTH_ID IN (<foreach collection="authIDs" item="authID" separator=",">#{authID}</foreach>)</if>
|
||||
ORDER BY AUTH_ID, GRP_ID
|
||||
<include refid="utility.paging-suffix" /></select>
|
||||
|
||||
<insert id="addActionGroups" parameterType="map">/* 권한-기능그룹 추가(authorityMapper.addActionGroups) */
|
||||
INSERT INTO TB_AUTH_ACTION (AUTH_ID, GRP_ID, REG_DT)
|
||||
SELECT AUTH_ID, GRP_ID,<include refid="utility.now" />
|
||||
FROM (<foreach collection="groupIDs" item="groupID" separator=" UNION">
|
||||
SELECT #{authID} AUTH_ID, #{groupID} GRP_ID FROM DUAL</foreach>
|
||||
) A
|
||||
WHERE NOT EXISTS (
|
||||
SELECT AUTH_ID, GRP_ID
|
||||
FROM TB_AUTH_ACTION B
|
||||
WHERE B.AUTH_ID = A.AUTH_ID
|
||||
AND B.GRP_ID = A.GRP_ID
|
||||
)</insert>
|
||||
|
||||
<delete id="removeActionGroups" parameterType="map">/* 권한-기능그룹 삭제(authorityMapper.removeActionGroups) */
|
||||
DELETE FROM TB_AUTH_ACTION
|
||||
<where>
|
||||
<if test="authIDs != null">AND AUTH_ID IN (<foreach collection="authIDs" item="authID" separator=",">#{authID}</foreach>)</if>
|
||||
<if test="groupIDs != null">AND GRP_ID IN (<foreach collection="groupIDs" item="groupID" separator=",">#{groupID}</foreach>)</if>
|
||||
</where>
|
||||
</delete>
|
||||
|
||||
<select id="getActionList" resultType="dataobject">/* 권한-기능 가져오기(authorityMapper.getActionList) */
|
||||
SELECT A.AUTH_ID
|
||||
, A.GRP_ID
|
||||
, C.ACTION
|
||||
FROM TB_AUTH_ACTION A
|
||||
, TB_ACTION_GRP B
|
||||
, TB_GRP_ACTION C
|
||||
WHERE A.GRP_ID = B.GRP_ID
|
||||
AND B.GRP_ID = C.GRP_ID
|
||||
ORDER BY A.AUTH_ID, A.GRP_ID, C.ACTION</select>
|
||||
|
||||
<sql id="selectAuthUser">
|
||||
<include refid="utility.paging-prefix" />
|
||||
SELECT *
|
||||
FROM TB_AUTH_USER
|
||||
<if test="authIDs != null">WHERE AUTH_ID IN (<foreach collection="authIDs" item="authID" separator=",">#{authID}</foreach>)</if>
|
||||
<if test="userIDs != null">WHERE USER_ID IN (<foreach collection="userIDs" item="userID" separator=",">#{userID}</foreach>)</if>
|
||||
<include refid="utility.orderBy"/>
|
||||
<include refid="utility.paging-suffix" /></sql>
|
||||
|
||||
<select id="getUserList" parameterType="map" resultType="dataobject">/* 권한-사용자 가져오기(authorityMapper.getUserList) */
|
||||
<include refid="selectAuthUser" /></select>
|
||||
|
||||
<select id="getUserAuths" parameterType="map" resultType="dataobject">/* 사용자-권한 가져오기(authorityMapper.getUserAuths) */
|
||||
<include refid="selectAuthUser" /></select>
|
||||
|
||||
<insert id="addUsers" parameterType="map">/* 권한-사용자 추가(authorityMapper.addUsers) */
|
||||
INSERT INTO TB_AUTH_USER (AUTH_ID, USER_ID, REG_DT)
|
||||
SELECT AUTH_ID, USER_ID,<include refid="utility.now" />
|
||||
FROM (<foreach collection="userIDs" item="userID" separator="UNION">
|
||||
SELECT #{authID} AUTH_ID, #{userID} USER_ID FROM DUAL</foreach>
|
||||
) A
|
||||
WHERE NOT EXISTS (
|
||||
SELECT AUTH_ID, USER_ID
|
||||
FROM TB_AUTH_USER B
|
||||
WHERE B.AUTH_ID = A.AUTH_ID
|
||||
AND B.USER_ID = A.USER_ID
|
||||
)</insert>
|
||||
|
||||
<delete id="removeUsers" parameterType="map">/* 권한-사용자 삭제(authorityMapper.removeUsers) */
|
||||
DELETE FROM TB_AUTH_USER
|
||||
<where>
|
||||
<if test="authIDs != null">AND AUTH_ID IN (<foreach collection="authIDs" item="authID" separator=",">#{authID}</foreach>)</if>
|
||||
<if test="userIDs != null">AND USER_ID IN (<foreach collection="userIDs" item="userID" separator=",">#{userID}</foreach>)</if>
|
||||
</where>
|
||||
</delete>
|
||||
|
||||
</mapper>
|
@ -0,0 +1,230 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cokr.xit.base.code.dao.CodeMapper">
|
||||
|
||||
<resultMap id="categoryRow" type="cokr.xit.base.code.CodeCategory">
|
||||
<result property="id" column="CTGR_ID"/>
|
||||
<result property="name" column="CTGR_NM"/>
|
||||
<result property="description" column="DSCRP"/>
|
||||
<result property="createdAt" column="REG_DT"/>
|
||||
<result property="createdBy" column="RGTR"/>
|
||||
<result property="lastModified" column="MDFCN_DT"/>
|
||||
<result property="modifiedBy" column="MDFR"/>
|
||||
<result property="useYN" column="USE_YN"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="groupRow" type="cokr.xit.base.code.CodeGroup">
|
||||
<result property="id" column="GRP_ID"/>
|
||||
<result property="name" column="GRP_NM"/>
|
||||
<result property="categoryID" column="CTGR_ID"/>
|
||||
<result property="description" column="DSCRP"/>
|
||||
<result property="createdAt" column="REG_DT"/>
|
||||
<result property="createdBy" column="RGTR"/>
|
||||
<result property="lastModified" column="MDFCN_DT"/>
|
||||
<result property="modifiedBy" column="MDFR"/>
|
||||
<result property="useYN" column="USE_YN"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="codeRow" type="cokr.xit.base.code.CommonCode">
|
||||
<result property="groupID" column="GRP_ID"/>
|
||||
<result property="code" column="CODE"/>
|
||||
<result property="value" column="CODE_VAL"/>
|
||||
<result property="description" column="DSCRP"/>
|
||||
<result property="etc1" column="ETC_1"/>
|
||||
<result property="etc2" column="ETC_2"/>
|
||||
<result property="etc3" column="ETC_3"/>
|
||||
<result property="sortOrder" column="SRT_ORD"/>
|
||||
<result property="createdAt" column="REG_DT"/>
|
||||
<result property="createdBy" column="RGTR"/>
|
||||
<result property="lastModified" column="MDFCN_DT"/>
|
||||
<result property="modifiedBy" column="MDFR"/>
|
||||
<result property="useYN" column="USE_YN"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectCategories"><include refid="utility.paging-prefix" />
|
||||
SELECT *
|
||||
FROM TB_CODE_CTGR
|
||||
WHERE USE_YN = 'Y'
|
||||
<if test="categoryIDs != null"> AND CTGR_ID IN (<foreach collection="categoryIDs" item="categoryID" separator=",">#{categoryID}</foreach>)</if>
|
||||
<include refid="utility.orderBy" />
|
||||
<include refid="utility.paging-suffix" /></sql>
|
||||
|
||||
<select id="getCategoryList" parameterType="map" resultType="dataobject">/* 코드 카테고리 목록 조회(codeMapper.getCategoryList) */
|
||||
<include refid="selectCategories" /></select>
|
||||
|
||||
<select id="getCategories" parameterType="map" resultMap="categoryRow">/*코드 카테고리 가져오기(codeMapper.getCategories)*/
|
||||
<include refid="selectCategories" /></select>
|
||||
|
||||
<insert id="insertCategory" parameterType="map">/* 코드 카테고리 등록(codeMapper.insertCategory) */
|
||||
INSERT INTO TB_CODE_CTGR (
|
||||
CTGR_ID
|
||||
, CTGR_NM
|
||||
, DSCRP
|
||||
, REG_DT
|
||||
, RGTR
|
||||
, MDFCN_DT
|
||||
, MDFR
|
||||
, USE_YN
|
||||
) VALUES (
|
||||
#{category.id}
|
||||
, #{category.name}
|
||||
, #{category.description}
|
||||
,<include refid="utility.now" />
|
||||
, #{currentUser.id}
|
||||
,<include refid="utility.now" />
|
||||
, #{currentUser.id}
|
||||
, 'Y'
|
||||
)</insert>
|
||||
|
||||
<update id="updateCategory" parameterType="map">/* 코드 카테고리 수정(codeMapper.updateCategory) */
|
||||
UPDATE TB_CODE_CTGR SET
|
||||
CTGR_NM = #{category.name}
|
||||
, DSCRP = #{category.description}
|
||||
, MDFCN_DT =<include refid="utility.now" />
|
||||
, MDFR = #{currentUser.id}
|
||||
WHERE CTGR_ID = #{category.id}</update>
|
||||
|
||||
<delete id="removeCategories" parameterType="map">/* 코드 카테고리 제거(codeMapper.removeCategories) */
|
||||
UPDATE TB_CODE_CTGR SET
|
||||
MDFCN_DT =<include refid="utility.now" />
|
||||
, MDFR = #{currentUser.id}
|
||||
, USE_YN = 'N'
|
||||
<if test='categoryIDs != null'>WHERE CTGR_ID IN (<foreach collection="categoryIDs" item="categoryID" separator=",">#{categoryID}</foreach>)</if></delete>
|
||||
|
||||
<sql id="selectGroups"><include refid="utility.paging-prefix" />
|
||||
SELECT *
|
||||
FROM TB_CODE_GRP
|
||||
WHERE USE_YN = 'Y'
|
||||
<if test="categoryIDs != null">AND CTGR_ID IN (<foreach collection="categoryIDs" item="categoryID" separator=",">#{categoryID}</foreach>)</if>
|
||||
<if test="groupIDs != null">AND GRP_ID IN (<foreach collection="groupIDs" item="groupID" separator=",">#{groupID}</foreach>)</if>
|
||||
<include refid="utility.orderBy" />
|
||||
<include refid="utility.paging-suffix" /></sql>
|
||||
|
||||
<select id="getGroupList" parameterType="dataobject" resultType="dataobject">/* 코드그룹 목록 조회(codeMapper.getGroupList) */
|
||||
<include refid="selectGroups" /></select>
|
||||
|
||||
<select id="getGroups" parameterType="map" resultMap="groupRow">/* 코드그룹 가져오기(codeMapper.getGroups) */
|
||||
<include refid="selectGroups" /></select>
|
||||
|
||||
<insert id="insertGroup" parameterType="map">/* 코드그룹 등록(codeMapper.insertGroup) */
|
||||
INSERT INTO TB_CODE_GRP (
|
||||
GRP_ID
|
||||
, GRP_NM
|
||||
, CTGR_ID
|
||||
, DSCRP
|
||||
, REG_DT
|
||||
, RGTR
|
||||
, MDFCN_DT
|
||||
, MDFR
|
||||
, USE_YN
|
||||
) VALUES (
|
||||
#{group.id}
|
||||
, #{group.name}
|
||||
, #{group.categoryID}
|
||||
, #{group.description}
|
||||
,<include refid="utility.now" />
|
||||
, #{currentUser.id}
|
||||
,<include refid="utility.now" />
|
||||
, #{currentUser.id}
|
||||
, 'Y'
|
||||
)</insert>
|
||||
|
||||
<update id="updateGroup" parameterType="map">/* 코드그룹 수정(codeMapper.updateGroup) */
|
||||
UPDATE TB_CODE_GRP SET
|
||||
GRP_NM = #{group.name}
|
||||
, CTGR_ID = #{group.categoryID}
|
||||
, DSCRP = #{group.description}
|
||||
, MDFCN_DT =<include refid="utility.now" />
|
||||
, MDFR = #{currentUser.id}
|
||||
WHERE GRP_ID = #{group.id}</update>
|
||||
|
||||
<update id="removeGroups" parameterType="map">/*코드그룹 제거(codeMapper.removeGroups) */
|
||||
UPDATE TB_CODE_GRP SET
|
||||
USE_YN = 'N'
|
||||
, MDFCN_DT =<include refid="utility.now" />
|
||||
, MDFR = #{currentUser.id}
|
||||
<where>
|
||||
<if test="categoryIDs != null">CTGR_ID IN (<foreach collection="categoryIDs" item="categoryID" separator=",">#{categoryID}</foreach>)</if>
|
||||
<if test="groupIDs != null">GRP_ID IN (<foreach collection="groupIDs" item="groupID" separator=",">#{groupID}</foreach>)</if>
|
||||
</where></update>
|
||||
|
||||
<sql id="selectCodes"><include refid="utility.paging-prefix" />
|
||||
SELECT *
|
||||
FROM TB_CMN_CODE
|
||||
WHERE USE_YN = 'Y'
|
||||
<if test='groupIDs != null'>AND GRP_ID IN (<foreach collection="groupIDs" item="groupID" separator=",">#{groupID}</foreach>)</if>
|
||||
<if test='codes != null'>AND CODE IN (<foreach collection="codes" item="code" separator=",">#{code}</foreach>)</if>
|
||||
<include refid="utility.orderBy" />
|
||||
<include refid="utility.paging-suffix" /></sql>
|
||||
|
||||
<select id="getCodeList" parameterType="map" resultType="dataobject">/* 그룹별 코드 가져오기(codeMapper.getCodeList) */
|
||||
<include refid="selectCodes" /></select>
|
||||
|
||||
<select id="getCodes" parameterType="map" resultMap="codeRow">/* 코드 가져오기(codeMapper.getCodes) */
|
||||
<include refid="selectCodes" /></select>
|
||||
|
||||
<insert id="insertCode" parameterType="map">/* 코드 등록(codeMapper.insertCode) */
|
||||
INSERT INTO TB_CMN_CODE (
|
||||
GRP_ID
|
||||
, CODE
|
||||
, CODE_VAL
|
||||
, DSCRP
|
||||
, ETC_1
|
||||
, ETC_2
|
||||
, ETC_3
|
||||
, SRT_ORD
|
||||
, REG_DT
|
||||
, RGTR
|
||||
, MDFCN_DT
|
||||
, MDFR
|
||||
, USE_YN
|
||||
) VALUES (
|
||||
#{code.groupID}
|
||||
, #{code.code}
|
||||
, #{code.value}
|
||||
, #{code.description}
|
||||
, #{code.etc1}
|
||||
, #{code.etc2}
|
||||
, #{code.etc3}
|
||||
, #{code.sortOrder}
|
||||
,<include refid="utility.now" />
|
||||
, #{currentUser.id}
|
||||
,<include refid="utility.now" />
|
||||
, #{currentUser.id}
|
||||
, 'Y'
|
||||
)</insert>
|
||||
|
||||
<update id="updateCode" parameterType="map">/* 코드 수정(codeMapper.updateCode) */
|
||||
UPDATE TB_CMN_CODE SET
|
||||
CODE_VAL = #{code.value}
|
||||
, DSCRP = #{code.description}
|
||||
, ETC_1 = #{code.etc1}
|
||||
, ETC_2 = #{code.etc2}
|
||||
, ETC_3 = #{code.etc3}
|
||||
, MDFCN_DT =<include refid="utility.now" />
|
||||
, MDFR = #{currentUser.id}
|
||||
WHERE GRP_ID = #{code.groupID}
|
||||
AND CODE = #{code.code}</update>
|
||||
|
||||
<update id="reorderCodes" parameterType="map">/* 코드 정렬순서 변경(codeMapper.reorderCodes) */
|
||||
UPDATE TB_CMN_CODE SET
|
||||
SRT_ORD = CASE CODE<foreach collection="codes" item="code" index="index" separator=" ">
|
||||
WHEN #{code} THEN #{index}</foreach>
|
||||
ELSE SRT_ORD
|
||||
END
|
||||
, MDFCN_DT =<include refid="utility.now" />
|
||||
, MDFR = #{currentUser.id}
|
||||
WHERE GRP_ID = #{groupID}
|
||||
AND CODE IN (<foreach collection="codes" item="code" separator=",">#{code}</foreach>)</update>
|
||||
|
||||
<update id="removeCodes" parameterType="map">/* 코드 제거(codeMapper.removeCodes) */
|
||||
UPDATE TB_CMN_CODE SET
|
||||
MDFCN_DT =<include refid="utility.now" />
|
||||
, MDFR = #{currentUser.id}
|
||||
, USE_YN = 'N'
|
||||
<where>
|
||||
<if test="groupIDs != null">AND GRP_ID IN (<foreach collection="groupIDs" item="groupID" separator=",">#{groupID}</foreach>)</if>
|
||||
<if test="codes != null">AND CODE IN (<foreach collection="codes" item="code" separator=",">#{code}</foreach>) </if>
|
||||
</where></update>
|
||||
|
||||
</mapper>
|
@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cokr.xit.base.file.dao.FileMapper">
|
||||
|
||||
<resultMap id="fileRow" type="cokr.xit.base.file.FileInfo">
|
||||
<result property="id" column="FILE_ID"/>
|
||||
<result property="infoType" column="INF_TYPE"/>
|
||||
<result property="infoKey" column="INF_KEY"/>
|
||||
<result property="subType" column="SUB_TYPE"/>
|
||||
<result property="name" column="FILE_NM"/>
|
||||
<result property="path" column="FILE_PATH"/>
|
||||
<result property="url" column="URL"/>
|
||||
<result property="mimeType" column="MIME_TYPE"/>
|
||||
<result property="size" column="FILE_SIZE"/>
|
||||
<result property="downloadCount" column="DNLD_CNT"/>
|
||||
<result property="sortOrder" column="SRT_ORD"/>
|
||||
<result property="createdAt" column="REG_DT"/>
|
||||
<result property="createdBy" column="RGTR"/>
|
||||
<result property="useYN" column="USE_YN"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="fileDirs">SELECT INF_TYPE
|
||||
, CONCAT('C://workspace/xit/base/files/', DIR, DATE_FORMAT(CURRENT_DATE, '%Y/%m/%d/')) DIR
|
||||
FROM (
|
||||
SELECT '00' INF_TYPE, 'attachment/' DIR UNION
|
||||
SELECT '01' INF_TYPE, 'document/' DIR UNION
|
||||
SELECT '02' INF_TYPE, 'article/' DIR
|
||||
) FILE_DIRS</sql>
|
||||
|
||||
<sql id="selectFiles">
|
||||
<if test="fileIDs != null">
|
||||
SELECT A.*, REPLACE(FILE_PATH, 'C://workspace/xit/base', '') URL
|
||||
FROM TB_FILE A
|
||||
WHERE FILE_ID IN (<foreach collection="fileIDs" item="fileID" separator=",">#{fileID}</foreach>)
|
||||
ORDER BY FILE_ID</if>
|
||||
<if test="fileIDs == null"><include refid="utility.paging-prefix" />
|
||||
SELECT A.*, REPLACE(FILE_PATH, 'C://workspace/xit/base', '') URL
|
||||
FROM TB_FILE A
|
||||
<where>
|
||||
<if test="infoType != null"> AND A.INF_TYPE = #{infoType}</if>
|
||||
<if test="infoKeys != null"> AND INF_KEY IN (<foreach collection="infoKeys" item="infoKey" separator=",">#{infoKey}</foreach>)</if>
|
||||
AND USE_YN = 'Y'
|
||||
</where>
|
||||
<include refid="utility.orderBy" />
|
||||
<include refid="utility.paging-suffix" /></if></sql>
|
||||
|
||||
<select id="getFileList" parameterType="map" resultType="dataobject">/* 파일 목록 조회(fileMapper.getFileList) */
|
||||
<include refid="selectFiles" /></select>
|
||||
|
||||
<select id="getFilesOf" parameterType="map" resultMap="fileRow">/* 파일 가져오기(fileMapper.getFilesOf) */
|
||||
<include refid="selectFiles" /></select>
|
||||
|
||||
<select id="getFiles" parameterType="map" resultMap="fileRow">/* 파일 가져오기(fileMapper.getFiles) */
|
||||
<include refid="selectFiles" /></select>
|
||||
|
||||
<insert id="insertFile" parameterType="map">/* 파일 등록(fileMapper.insertFile) */
|
||||
<selectKey keyProperty="file.id,file.path" keyColumn="NEW_ID,PATH" resultType="map" order="BEFORE">
|
||||
SELECT NEW_ID, CONCAT(DIR, NEW_ID, '.', #{file.extension}) PATH
|
||||
FROM (
|
||||
SELECT IFNULL(MAX(FILE_ID) + 1, CONCAT(THIS_DAY, '00001')) NEW_ID
|
||||
FROM TB_FILE A, (<include refid="utility.selectThisDay" />) B
|
||||
WHERE FILE_ID LIKE CONCAT(THIS_DAY, '%')
|
||||
) T1, (
|
||||
<include refid="fileDirs" />
|
||||
WHERE INF_TYPE = #{file.infoType}
|
||||
) T2</selectKey>
|
||||
INSERT INTO TB_FILE (
|
||||
FILE_ID
|
||||
, INF_TYPE
|
||||
, INF_KEY
|
||||
, SUB_TYPE
|
||||
, FILE_NM
|
||||
, FILE_PATH
|
||||
, MIME_TYPE
|
||||
, FILE_SIZE
|
||||
, DNLD_CNT
|
||||
, SRT_ORD
|
||||
, RGTR
|
||||
, REG_DT
|
||||
, USE_YN
|
||||
) VALUES (
|
||||
#{file.id}
|
||||
, #{file.infoType}
|
||||
, #{file.infoKey}
|
||||
, #{file.subType}
|
||||
, #{file.name}
|
||||
, #{file.path}
|
||||
, #{file.mimeType}
|
||||
, #{file.size}
|
||||
, #{file.downloadCount}
|
||||
, #{file.sortOrder}
|
||||
, #{currentUser.id}
|
||||
,<include refid="utility.now" />
|
||||
, 'Y'
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="reorder" parameterType="map">/* 파일 순서 변경(fileMapper.reorder) */
|
||||
UPDATE TB_FILE SET
|
||||
SRT_ORD = CASE FILE_ID
|
||||
<foreach collection="fileIDs" item="fileID" index="index" separator=" ">WHEN #{fileID} THEN #{index}
|
||||
</foreach>
|
||||
ELSE SRT_ORD END
|
||||
WHERE FILE_ID IN (<foreach collection="fileIDs" item="fileID" separator=",">#{fileID}</foreach>)</update>
|
||||
|
||||
<update id="updateDownloadCount" parameterType="map">/* 다운로드 횟수 증가(fileMapper.updateDownloadCount) */
|
||||
UPDATE TB_FILE SET
|
||||
DNLD_CNT = DNLD_CNT + 1
|
||||
WHERE USE_YN = 'Y'
|
||||
AND FILE_ID IN (<foreach collection="fileIDs" item="fileID" separator=",">#{fileID}</foreach>)</update>
|
||||
|
||||
<update id="removeFiles" parameterType="map">/* 파일 제거(fileMapper.removeFiles) */
|
||||
UPDATE TB_FILE SET
|
||||
USE_YN = 'N'
|
||||
WHERE USE_YN = 'Y'
|
||||
<if test="fileIDs != null"> AND FILE_ID IN (<foreach collection="fileIDs" item="fileID" separator=",">#{fileID}</foreach>)</if>
|
||||
<if test="infoKeys != null">
|
||||
AND INF_TYPE = #{infoType}
|
||||
AND INF_KEY IN (<foreach collection="infoKeys" item="infoKey" separator=",">#{infoKey}</foreach>)</if></update>
|
||||
|
||||
<delete id="deleteFiles" parameterType="map">/* 파일 삭제(fileMapper.deleteFiles) */
|
||||
DELETE FROM TB_FILE
|
||||
<if test="fileIDs != null">WHERE FILE_ID IN (<foreach collection="fileIDs" item="fileID" separator=",">#{fileID}</foreach>)</if>
|
||||
</delete>
|
||||
|
||||
</mapper>
|
@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cokr.xit.base.menu.dao.MenuMapper">
|
||||
|
||||
<resultMap id="menuRow" type="cokr.xit.base.menu.Menu">
|
||||
<result property="id" column="MENU_NO"/>
|
||||
<result property="name" column="MENU_NM"/>
|
||||
<result property="programFilename" column="PGRM_FILE_NM"/>
|
||||
<result property="action" column="ACTION"/>
|
||||
<result property="description" column="DSCRP"/>
|
||||
<result property="parentID" column="PRNT_NO"/>
|
||||
<result property="imageName" column="IMG_NM"/>
|
||||
<result property="imageConf" column="IMG_CNF"/>
|
||||
<result property="sortOrder" column="SRT_ORD"/>
|
||||
<result property="createdAt" column="REG_DT"/>
|
||||
<result property="createdBy" column="RGTR"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectMenus">
|
||||
SELECT A.*
|
||||
FROM TB_MENU A
|
||||
<if test='menuID != null'>WHERE MENU_NO = #{menuID}</if>
|
||||
ORDER BY PRNT_NO, SRT_ORD, MENU_NO</sql>
|
||||
|
||||
<select id="getMenus" parameterType="map" resultMap="menuRow">/* 메뉴 정보 조회(menuMapper.getMenus) */
|
||||
<include refid="selectMenus" /></select>
|
||||
|
||||
<select id="getMenu" parameterType="int" resultMap="menuRow">/* 메뉴 가져오기(menuMapper.getMenu) */
|
||||
<include refid="selectMenus" /></select>
|
||||
|
||||
<insert id="insertMenu" parameterType="map">/* 메뉴 등록(menuMapper.insertMenu) */
|
||||
<selectKey order="BEFORE" resultType="map" keyColumn="NEW_NO,NEW_ORD" keyProperty="menu.id,menu.sortOrder">
|
||||
SELECT NEW_NO, NEW_ORD
|
||||
FROM (SELECT IFNULL(MAX(MENU_NO) + 1, 0) NEW_NO FROM TB_MENU) A,
|
||||
(<include refid="newSortOrder" />) B</selectKey>
|
||||
INSERT INTO TB_MENU (
|
||||
MENU_NO
|
||||
, MENU_NM
|
||||
, PRNT_NO
|
||||
, PGRM_FILE_NM
|
||||
, ACTION
|
||||
, DSCRP
|
||||
, IMG_NM
|
||||
, IMG_CNF
|
||||
, SRT_ORD
|
||||
, REG_DT
|
||||
, RGTR
|
||||
) VALUES (
|
||||
#{menu.id}
|
||||
, #{menu.name}
|
||||
, #{menu.parentID}
|
||||
, #{menu.programFilename}
|
||||
, #{menu.action}
|
||||
, #{menu.description}
|
||||
, #{menu.imageName}
|
||||
, #{menu.imageConf}
|
||||
, #{menu.sortOrder}
|
||||
,<include refid="utility.now" />
|
||||
, #{currentUser.id}
|
||||
)</insert>
|
||||
|
||||
<update id="updateMenu" parameterType="map">/* 메뉴 수정(menuMapper.updateMenu) */
|
||||
UPDATE TB_MENU SET
|
||||
MENU_NM = #{menu.name}
|
||||
, PGRM_FILE_NM = #{menu.programFilename}
|
||||
, ACTION = #{menu.action}
|
||||
, DSCRP = #{menu.description}
|
||||
, IMG_NM = #{menu.imageName}
|
||||
, IMG_CNF = #{menu.imageConf}
|
||||
WHERE MENU_NO = #{menu.id}</update>
|
||||
|
||||
<sql id="newSortOrder">SELECT IFNULL(MAX(SRT_ORD) + 1, 0) NEW_ORD FROM TB_MENU WHERE PRNT_NO = IFNULL(#{parentID}, IFNULL(#{menu.parentID}, 0))</sql>
|
||||
|
||||
<update id="moveMenus" parameterType="map">/* 메뉴 이동(menuMapper.moveMenus) */
|
||||
UPDATE TB_MENU SET
|
||||
PRNT_NO = #{parentID}
|
||||
, SRT_ORD = SRT_ORD + (<include refid="newSortOrder" />)
|
||||
WHERE MENU_NO IN (<foreach collection="menuIDs" item="menuID" separator=",">#{menuID}</foreach>)
|
||||
</update>
|
||||
|
||||
<update id="reorderMenus" parameterType="map">/* 메뉴 순서 변경(menuMapper.reorderMenus) */
|
||||
UPDATE TB_MENU SET
|
||||
SRT_ORD = CASE MENU_NO
|
||||
<foreach collection="menuIDs" item="menuID" index="index">WHEN #{menuID} THEN #{index}
|
||||
</foreach>
|
||||
ELSE MENU_NO END
|
||||
WHERE MENU_NO IN (<foreach collection="menuIDs" item="menuID" separator=",">#{menuID}</foreach>)</update>
|
||||
|
||||
<delete id="removeMenus" parameterType="map">/* 메뉴 제거(menuMapper.removeMenus) */
|
||||
DELETE FROM TB_MENU
|
||||
WHERE MENU_NO IN (<foreach collection="menuIDs" item="menuID" separator=",">#{menuID}</foreach>)
|
||||
</delete>
|
||||
|
||||
</mapper>
|
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cokr.xit.base.security.authentication.dao.PolicyMapper">
|
||||
|
||||
<resultMap id="policyRow" type="cokr.xit.base.security.authentication.AuthenticationPolicy">
|
||||
<result property="userID" column="USER_ID"/>
|
||||
<result property="ipAddress" column="IP_ADRS"/>
|
||||
<result property="duplicateYN" column="DPLCT_YN"/>
|
||||
<result property="limitYN" column="LIMIT_YN"/>
|
||||
<result property="createdBy" column="RGTR"/>
|
||||
<result property="createdAt" column="REG_DT"/>
|
||||
<result property="modifiedBy" column="MDFR"/>
|
||||
<result property="lastModified" column="MDFCN_DT"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="getPolicyList" parameterType="map" resultType="dataobject">/* 로그인 정책 목록 조회(policyMapper.getPolicyList) */
|
||||
<include refid="utility.paging-prefix"/>
|
||||
SELECT A.USER_ID
|
||||
, USER_NM
|
||||
, IP_ADRS
|
||||
, DPLCT_YN
|
||||
, LIMIT_YN
|
||||
, MDFR
|
||||
, MDFCN_DT
|
||||
FROM TB_USER A LEFT OUTER JOIN TB_LOGIN_POLICY B ON A.USER_ID = B.USER_ID
|
||||
<if test="term != null">WHERE A.${by} LIKE CONCAT('%', #{term}, '%')</if>
|
||||
<include refid="utility.orderBy" />
|
||||
<include refid="utility.paging-suffix"/></select>
|
||||
|
||||
<select id="getPolicies" parameterType="map" resultMap="policyRow">/* 로그인 정책 가져오기(policyMapper.getPolicies) */
|
||||
SELECT *
|
||||
FROM TB_LOGIN_POLICY
|
||||
<if test="userIDs != null">WHERE USER_ID IN (<foreach collection="userIDs" item="userID" separator=",">#{userID}</foreach>)</if>
|
||||
ORDER BY USER_ID</select>
|
||||
|
||||
<insert id="insertPolicy" parameterType="map">/* 로그인 정책 등록(policyMapper.insertPolicy) */
|
||||
INSERT INTO TB_LOGIN_POLICY (
|
||||
USER_ID
|
||||
, IP_ADRS
|
||||
, DPLCT_YN
|
||||
, LIMIT_YN
|
||||
, REG_DT
|
||||
, RGTR
|
||||
, MDFCN_DT
|
||||
, MDFR
|
||||
) VALUES (
|
||||
#{policy.userID}
|
||||
, #{policy.ipAddress}
|
||||
, #{policy.duplicateYN}
|
||||
, #{policy.limitYN}
|
||||
,<include refid="utility.now" />
|
||||
, #{currentUser.id}
|
||||
,<include refid="utility.now" />
|
||||
, #{currentUser.id}
|
||||
)</insert>
|
||||
|
||||
<update id="updatePolicy" parameterType="map">/* 로그인 정책 수정(policyMapper.updatePolicy) */
|
||||
UPDATE TB_LOGIN_POLICY SET
|
||||
IP_ADRS = #{policy.ipAddress}
|
||||
, DPLCT_YN = #{policy.duplicateYN}
|
||||
, LIMIT_YN = #{policy.limitYN}
|
||||
, MDFR = #{currentUser.id}
|
||||
, MDFCN_DT =<include refid="utility.now" />
|
||||
WHERE USER_ID = #{policy.userID}</update>
|
||||
|
||||
<delete id="removePolicy" parameterType="map">/* 로그인 정책 삭제(policyMapper.removePolicy) */
|
||||
DELETE FROM TB_LOGIN_POLICY
|
||||
WHERE USER_ID IN (<foreach collection="userIDs" item="userID" separator=",">#{userID}</foreach>)</delete>
|
||||
|
||||
</mapper>
|
@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="program">
|
||||
|
||||
<resultMap id="programRow" type="cokr.xit.base.menu.Program">
|
||||
<result property="filename" column="PGRM_FILE_NM"/>
|
||||
<result property="location" column="PGRM_FILE_PATH"/>
|
||||
<result property="name" column="PGRM_NM"/>
|
||||
<result property="description" column="DSCRP"/>
|
||||
<result property="url" column="URL"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="reqRow" type="cokr.xit.base.menu.ChangeRequest">
|
||||
<result property="filename" column="PGRM_FILE_NM"/>
|
||||
<result property="id" column="REQ_ID"/>
|
||||
<result property="subject" column="SUBJECT"/>
|
||||
<result property="requestorID" column="REQ_USER"/>
|
||||
<result property="requestDate" column="REQ_DT"/>
|
||||
<result property="requestDetail" column="REQ_CNTNT"/>
|
||||
<result property="processorID" column="PRSC_USER"/>
|
||||
<result property="processDate" column="PRCS_DT"/>
|
||||
<result property="processDetail" column="PRCS_CNTNT"/>
|
||||
<result property="status" column="PRCS_STATUS"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectPrograms">
|
||||
<include refid="utility.paging-prefix"/>
|
||||
SELECT A.*
|
||||
FROM TB_PROGRAM A
|
||||
<where>
|
||||
<if test="by != null and term != null">${by} LIKE CONCAT('%', #{term}, '%')</if>
|
||||
<if test='filenames != null'>PGRM_FILE_NM IN (<foreach collection="filenames" item="filename" separator=",">#{filename}</foreach>)</if>
|
||||
</where>
|
||||
ORDER BY<if test='by != null'>${by}</if><if test='by == null'>PGRM_FILE_NM</if>
|
||||
<include refid="utility.paging-suffix"/></sql>
|
||||
|
||||
<select id="getProgramList" parameterType="map" resultType="dataobject">/* 프로그램 목록 조회(program.getProgramList) */
|
||||
<include refid="selectPrograms"/></select>
|
||||
|
||||
<select id="getPrograms" parameterType="map" resultMap="programRow">/* 프로그램 가져오기(program.getPrograms) */
|
||||
<include refid="selectPrograms"/></select>
|
||||
|
||||
<insert id="insertProgram" parameterType="cokr.xit.base.menu.Program">/* 프로그램 등록(program.insertProgram) */
|
||||
INSERT INTO TB_PROGRAM (
|
||||
PGRM_FILE_NM
|
||||
, PGRM_FILE_PATH
|
||||
, PGRM_NM
|
||||
, DSCRP
|
||||
, URL
|
||||
) VALUES (
|
||||
#{filename}
|
||||
, #{location}
|
||||
, #{name}
|
||||
, #{description}
|
||||
, #{url}
|
||||
)</insert>
|
||||
|
||||
<update id="updateProgram" parameterType="cokr.xit.base.menu.Program">/* 프로그램 수정(program.updateProgram) */
|
||||
UPDATE TB_PROGRAM SET
|
||||
PGRM_FILE_PATH = #{location}
|
||||
, PGRM_NM = #{name}
|
||||
, DSCRP = #{description}
|
||||
, URL = #{url}
|
||||
WHERE PGRM_FILE_NM = #{filename}</update>
|
||||
|
||||
<delete id="removePrograms" parameterType="map">/* 프로그램 삭제(program.removePrograms) */
|
||||
DELETE FROM TB_PROGRAM
|
||||
WHERE PGRM_FILE_NM IN (<foreach collection="filenames" item="filename" separator=",">#{filename}</foreach>)</delete>
|
||||
|
||||
<delete id="clearPrograms" parameterType="map">/* 프로그램 비우기(program.clearPrograms) */
|
||||
DELETE FROM TB_PROGRAM
|
||||
WHERE PGRM_FILE_NM NOT IN (SELECT PGRM_FILE_NM FROM TB_MENU)</delete>
|
||||
|
||||
<sql id="selectRequests">
|
||||
SELECT A.*
|
||||
FROM TB_PGRM_CHNG_REQ A
|
||||
<where>
|
||||
<if test='fromReqDate != null'>REQ_DT >= #{fromReqDate}</if>
|
||||
<if test='toReqDate != null'>REQ_DT <= #{toReqDate}</if>
|
||||
<if test="by != null and term != null">${by} LIKE CONCAT('%', #{term}, '%')</if>
|
||||
<if test='filenames != null'>PGRM_FILE_NAME IN (<foreach collection="filenames" item="filename" separator=",">#{filename}</foreach>)</if>
|
||||
<if test='reqIDs != null'>REQ_ID IN (<foreach collection="reqIDs" item="reqID" separator=",">#{reqID}</foreach>)</if>
|
||||
</where>
|
||||
ORDER BY PGRM_FILE_NM,<if test='by != null'>${by}</if><if test='by == null'>REQ_ID DESC</if></sql>
|
||||
|
||||
<select id="getRequestList" parameterType="map" resultType="dataobject">/* 변경요청 목록 조회(program.getRequestList) */
|
||||
<include refid="selectRequests" /></select>
|
||||
|
||||
<select id="getRequests" parameterType="map" resultType="dataobject">/* 프로그램별 변경요청 목록 조회(program.getRequests) */
|
||||
<include refid="selectRequests" /></select>
|
||||
|
||||
<insert id="insertRequest" parameterType="cokr.xit.base.menu.ChangeRequest">/* 프로그램 변경요청 등록(program.insertRequest) */
|
||||
INSERT INTO TB_PGRM_CHNG_REQ (
|
||||
PGRM_FILE_NM
|
||||
, REQ_ID
|
||||
, SUBJECT
|
||||
, REQ_USER
|
||||
, REQ_DT
|
||||
, REQ_CNTNT
|
||||
, PRSC_USER
|
||||
, PRCS_DT
|
||||
, PRCS_CNTNT
|
||||
, PRCS_STATUS
|
||||
) VALUES (
|
||||
#{filename}
|
||||
, #{id}
|
||||
, #{subject}
|
||||
, #{requestorID}
|
||||
, #{requestDate}
|
||||
, #{requestDetail}
|
||||
, #{processorID}
|
||||
, #{processDate}
|
||||
, #{processDetail}
|
||||
, #{status}
|
||||
)</insert>
|
||||
|
||||
<update id="updateRequest" parameterType="cokr.xit.base.menu.ChangeRequest">/* 프로그램 변경요청 수정(program.updateRequest) */
|
||||
UPDATE TB_PGRM_CHNG_REQ SET
|
||||
SUBJECT = #{subject}
|
||||
, REQ_USER = #{requestorID}
|
||||
, REQ_DT = #{requestDate}
|
||||
, REQ_CNTNT = #{requestDetail}
|
||||
, PRSC_USER = #{processorID}
|
||||
, PRCS_DT = #{processDate}
|
||||
, PRCS_CNTNT = #{processDetail}
|
||||
WHERE PGRM_FILE_NM = #{filename}
|
||||
AND REQ_ID = #{id}</update>
|
||||
|
||||
<update id="setRequestStatus" parameterType="map">/* 프로그램 변경요청 상태 변경(program.setRequestStatus) */
|
||||
UPDATE TB_PGRM_CHNG_REQ SET
|
||||
PRCS_STATUS = #{status}
|
||||
WHERE PGRM_FILE_NM = #{filename}
|
||||
AND REQ_ID = #{id}</update>
|
||||
|
||||
</mapper>
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cokr.xit.foundation.test.TestMapper">
|
||||
|
||||
<insert id="insert" parameterType="map">${sql}</insert>
|
||||
|
||||
<update id="update" parameterType="map">${sql}</update>
|
||||
|
||||
<delete id="delete" parameterType="map">${sql}</delete>
|
||||
|
||||
<update id="commit">COMMIT</update>
|
||||
|
||||
</mapper>
|
@ -0,0 +1,221 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<!-- 업무 사용자 -->
|
||||
<mapper namespace="cokr.xit.base.user.dao.UserMapper">
|
||||
|
||||
<resultMap id="userRow" type="cokr.xit.base.user.ManagedUser">
|
||||
<result property="id" column="USER_ID"/>
|
||||
<result property="account" column="USER_ACNT"/>
|
||||
<result property="name" column="USER_NM"/>
|
||||
<result property="password" column="PASSWD"/>
|
||||
<result property="passwordHint" column="PASSWD_HINT"/>
|
||||
<result property="passwordHintAnswer" column="PASSWD_NSR"/>
|
||||
<result property="empNo" column="EMP_NO"/>
|
||||
<result property="residentRegNo" column="RSDNT_NO"/>
|
||||
<result property="gender" column="GENDER"/>
|
||||
<result property="birthday" column="BRDT"/>
|
||||
<result property="areaNo" column="AREA_NO"/>
|
||||
<result property="zipCode" column="ZIP"/>
|
||||
<result property="address" column="ADDR"/>
|
||||
<result property="addressDetail" column="DADDR"/>
|
||||
<result property="phoneNo" column="TELNO"/>
|
||||
<result property="mobilePhoneNo" column="MBL_TELNO"/>
|
||||
<result property="faxNo" column="FXNO"/>
|
||||
<result property="emailAddress" column="EML_ADRS"/>
|
||||
<result property="positionName" column="POS_NM"/>
|
||||
<result property="groupID" column="GRP_ID"/>
|
||||
<result property="orgID" column="ORG_ID"/>
|
||||
<result property="deptCode" column="DEPT_CD"/>
|
||||
<result property="institute" column="NSTT_CD"/>
|
||||
<result property="certificateDn" column="CRTFC_DN"/>
|
||||
<result property="locked" column="LOCK_YN"/>
|
||||
<result property="lockCount" column="LOCK_CNT"/>
|
||||
<result property="lockedDate" column="LOCK_DT"/>
|
||||
<result property="createdAt" column="REG_DT"/>
|
||||
<result property="createdBy" column="RGTR"/>
|
||||
<result property="lastModified" column="MDFCN_DT"/>
|
||||
<result property="modifiedBy" column="MDFR"/>
|
||||
<result property="useYN" column="USE_YN"/>
|
||||
<result property="status" column="STTS"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectUsers"><include refid="utility.paging-prefix" />
|
||||
SELECT USER_ID
|
||||
, USER_ACNT
|
||||
, USER_NM
|
||||
, PASSWD_HINT
|
||||
, PASSWD_NSR
|
||||
, EMP_NO
|
||||
, RSDNT_NO
|
||||
, GENDER
|
||||
, BRDT
|
||||
, AREA_NO
|
||||
, ZIP
|
||||
, ADDR
|
||||
, DADDR
|
||||
, TELNO
|
||||
, MBL_TELNO
|
||||
, FXNO
|
||||
, EML_ADRS
|
||||
, POS_NM
|
||||
, GRP_ID
|
||||
, ORG_ID
|
||||
, DEPT_CD
|
||||
, NSTT_CD
|
||||
, CRTFC_DN
|
||||
, LOCK_YN
|
||||
, LOCK_CNT
|
||||
, LOCK_DT
|
||||
, REG_DT
|
||||
, STTS
|
||||
FROM TB_USER
|
||||
<where><if test="by != null and term != null">AND ${by} LIKE CONCAT('%', #{term}, '%')</if>
|
||||
<if test="userIDs != null">USER_ID IN (<foreach collection="userIDs" item="userID" separator=",">#{userID}</foreach>)</if>
|
||||
<if test="status == null and userIDs == null">AND STTS != 'D'</if>
|
||||
<if test="status != null">AND STTS = #{status}</if></where>
|
||||
<include refid="utility.orderBy" />
|
||||
<include refid="utility.paging-suffix" /></sql>
|
||||
|
||||
<select id="getUserList" parameterType="map" resultType="dataobject">/* 사용자 목록 조회(userMapper.getUserList) */
|
||||
<include refid="selectUsers"/></select>
|
||||
|
||||
<select id="getUsers" parameterType="map" resultMap="userRow">/* 사용자 가져오기(userMapper.getUsers) */
|
||||
<include refid="selectUsers"/></select>
|
||||
|
||||
<select id="getUser" parameterType="map" resultMap="userRow">/* 사용자 계정 가져오기(userMapper.getUser) */
|
||||
SELECT *
|
||||
FROM TB_USER
|
||||
WHERE USER_ACNT = #{account}
|
||||
AND NSTT_CD = #{institute}</select>
|
||||
|
||||
<insert id="insertUser" parameterType="cokr.xit.base.user.ManagedUser">
|
||||
<selectKey resultType="string" keyProperty="id" keyColumn="NEW_ID" order="BEFORE">SELECT LPAD(IFNULL(MAX(USER_ID) + 1, 1), 10, '0') NEW_ID FROM TB_USER</selectKey>
|
||||
/* 사용자 정보 등록(userMapper.insertUser) */
|
||||
INSERT INTO TB_USER (
|
||||
USER_ID
|
||||
, USER_ACNT
|
||||
, USER_NM
|
||||
, PASSWD
|
||||
, PASSWD_HINT
|
||||
, PASSWD_NSR
|
||||
, EMP_NO
|
||||
, RSDNT_NO
|
||||
, GENDER
|
||||
, BRDT
|
||||
, AREA_NO
|
||||
, ZIP
|
||||
, ADDR
|
||||
, DADDR
|
||||
, TELNO
|
||||
, MBL_TELNO
|
||||
, FXNO
|
||||
, EML_ADRS
|
||||
, POS_NM
|
||||
, GRP_ID
|
||||
, ORG_ID
|
||||
, NSTT_CD
|
||||
, CRTFC_DN
|
||||
, LOCK_YN
|
||||
, LOCK_CNT
|
||||
, LOCK_DT
|
||||
, REG_DT
|
||||
, RGTR
|
||||
, MDFCN_DT
|
||||
, MDFR
|
||||
, USE_YN
|
||||
, STTS
|
||||
) VALUES (
|
||||
#{id}
|
||||
, #{account}
|
||||
, #{name}
|
||||
, #{password}
|
||||
, #{passwordHint}
|
||||
, #{passwordHintAnswer}
|
||||
, #{empNo}
|
||||
, #{residentRegNo}
|
||||
, #{gender}
|
||||
, #{birthday}
|
||||
, #{areaNo}
|
||||
, #{zipCode}
|
||||
, #{address}
|
||||
, #{addressDetail}
|
||||
, #{phoneNo}
|
||||
, #{mobilePhoneNo}
|
||||
, #{faxNo}
|
||||
, #{emailAddress}
|
||||
, #{positionName}
|
||||
, #{groupID}
|
||||
, #{orgID}
|
||||
, #{institute}
|
||||
, #{certificateDn}
|
||||
, 'N'
|
||||
, 0
|
||||
, NULL
|
||||
,<include refid="utility.now" />
|
||||
, #{createdBy}
|
||||
,<include refid="utility.now" />
|
||||
, #{createdBy}
|
||||
, 'Y'
|
||||
, #{status}
|
||||
)</insert>
|
||||
|
||||
<update id="updateUser" parameterType="cokr.xit.base.user.ManagedUser">/* 사용자 정보 수정(userMapper.updateUser) */
|
||||
UPDATE TB_USER SET
|
||||
USER_NM = #{name}
|
||||
, PASSWD_HINT = #{passwordHint}
|
||||
, PASSWD_NSR = #{passwordHintAnswer}
|
||||
, EMP_NO = #{empNo}
|
||||
, RSDNT_NO = #{residentRegNo}
|
||||
, GENDER = #{gender}
|
||||
, BRDT = #{birthday}
|
||||
, AREA_NO = #{areaNo}
|
||||
, ZIP = #{zipCode}
|
||||
, ADDR = #{address}
|
||||
, DADDR = #{addressDetail}
|
||||
, TELNO = #{phoneNo}
|
||||
, MBL_TELNO = #{mobilePhoneNo}
|
||||
, FXNO = #{faxNo}
|
||||
, EML_ADRS = #{emailAddress}
|
||||
, POS_NM = #{positionName}
|
||||
, GRP_ID = #{groupID}
|
||||
, ORG_ID = #{orgID}
|
||||
, NSTT_CD = #{institute}
|
||||
, CRTFC_DN = #{certificateDn}
|
||||
, MDFCN_DT =<include refid="utility.now" />
|
||||
, MDFR = #{modifiedBy}
|
||||
WHERE USER_ID = #{id}</update>
|
||||
|
||||
<update id="changePassword" parameterType="map">/* 비밀번호 변경(userMapper.changePassword) */
|
||||
UPDATE TB_USER SET
|
||||
PASSWD = CASE USER_ID<foreach collection="userPasswords" item="userPassword" separator=" ">
|
||||
WHEN #{userPassword.userID} THEN #{userPassword.password}</foreach>
|
||||
ELSE PASSWD END
|
||||
, MDFCN_DT =<include refid="utility.now" />
|
||||
, MDFR = #{currentUser.id}
|
||||
WHERE USER_ID IN (<foreach collection="userIDs" item="userID" separator=",">#{userID}</foreach>)
|
||||
</update>
|
||||
|
||||
<update id="lockUsers" parameterType="map">/* 사용자 잠김 해제(userMapper.lockUsers) */
|
||||
UPDATE TB_USER SET
|
||||
<if test='lock == true'> LOCK_YN = 'Y'
|
||||
, LOCK_CNT = LOCK_CNT + 1
|
||||
, LOCK_DT =<include refid="utility.now" /></if>
|
||||
<if test='lock == false'> LOCK_YN = 'N'
|
||||
, LOCK_CNT = 0
|
||||
, LOCK_DT = NULL</if>
|
||||
, MDFCN_DT =<include refid="utility.now" />
|
||||
, MDFR = #{currentUser.id}
|
||||
WHERE USER_ID IN (<foreach collection="userIDs" item="userID" separator=",">#{userID}</foreach>)
|
||||
</update>
|
||||
|
||||
<update id="setStatus" parameterType="map">/* 사용자 상태 변경(userMapper.setStatus) */
|
||||
UPDATE TB_USER SET
|
||||
STTS = #{status}
|
||||
<if test='"D" == status'>, USE_YN = 'N'</if>
|
||||
, MDFCN_DT =<include refid="utility.now" />
|
||||
, MDFR = #{currentUser.id}
|
||||
WHERE USER_ID IN (<foreach collection="userIDs" item="userID" separator=",">#{userID}</foreach>)
|
||||
AND STTS != #{status}
|
||||
</update>
|
||||
|
||||
</mapper>
|
@ -0,0 +1,80 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<form id="infoPrefix-form">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="id"
|
||||
>아이디</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="id" type="text" required data-map="GRP_ID" maxlength="50" class="form-control" placeholder="prefixName 아이디" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="name"
|
||||
>이름</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="name" type="text" required data-map="GRP_NM" maxlength="60" class="form-control" placeholder="prefixName 이름" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="description"
|
||||
>설명</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="description" type="text" data-map="DSCRP" maxlength="200" class="form-control dob-picker" placeholder="prefixName 설명"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4 justify-content-end">
|
||||
<div class="col-sm-12" style="text-align:right;">
|
||||
<button onclick="saveinfoPrefix();" type="button" class="btn btn-primary">저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
|
||||
var infoPrefixFields = new FormFields("#infoPrefix-form");
|
||||
|
||||
infoPrefixControl.groups.setInfo = obj => {
|
||||
infoPrefixFields.set(obj);
|
||||
let create = isEmpty(obj.data.GRP_ID);
|
||||
$("input[name='id']").prop("readonly", !create);
|
||||
$("#infoPrefix-form input")
|
||||
.change(function() {
|
||||
let input = $(this),
|
||||
name = input.attr("data-map"),
|
||||
val = input.val();
|
||||
infoPrefixControl.groups.setValue(name, val);
|
||||
})
|
||||
.onEnterPress(saveinfoPrefix);
|
||||
|
||||
document.querySelector("input[name='" + (create ? "id" : "name") + "']").focus();
|
||||
}
|
||||
|
||||
infoPrefixControl.groups.onModify = (changed) => {
|
||||
if (["GRP_NM"].filter(e => changed.includes(e)).length < 1)
|
||||
return;
|
||||
|
||||
renderinfoPrefixList();
|
||||
infoPrefixControl.groups.dataset.setState();
|
||||
}
|
||||
|
||||
function saveinfoPrefix() {
|
||||
if (!$("#infoPrefix-form input").validInputs()) return;
|
||||
|
||||
dialog.alert({
|
||||
content:"현재 prefixName 정보를 저장하시겠습니까?",
|
||||
onOK:() => {
|
||||
infoPrefixControl.groups.save(infoPrefixFields.get());
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceURL=actionGroup-info.jsp
|
||||
</script>
|
@ -0,0 +1,264 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<jsp:include page="/WEB-INF/jsp/include/head.jsp" />
|
||||
<body>
|
||||
<!-- Layout wrapper -->
|
||||
<div class="layout-wrapper layout-content-navbar">
|
||||
<div class="layout-container">
|
||||
<jsp:include page="/WEB-INF/jsp/include/userMenus.jsp" />
|
||||
<!-- Layout container -->
|
||||
<!-- Layout page -->
|
||||
<div class="layout-page">
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/top.jsp" />
|
||||
|
||||
<!-- Content wrapper -->
|
||||
<div class="content-wrapper">
|
||||
<!-- Content -->
|
||||
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<%--h4 id="pageTitle" class="fw-bold py-3 mb-4">페이지 제목</h4--%>
|
||||
<c:set var="prefixName" scope="request">기능 그룹</c:set>
|
||||
<!-- Page Body -->
|
||||
<div class="card">
|
||||
<div class="card-datatable text-nowrap">
|
||||
<div id="DataTables_Table_0_wrapper" class="dataTables_wrapper dt-bootstrap5 no-footer">
|
||||
|
||||
<div class="d-flex flex-row justify-content-evenly">
|
||||
<div style="width:49%;">
|
||||
<h5 class="mt-3">기능 그룹</h5>
|
||||
<div class="d-flex flex-row justify-content-between p-3">
|
||||
<div>
|
||||
<div class="input-group" id="DataTables_Table_0_length">
|
||||
<select id="by" onchange="document.getElementById('term').focus();" aria-controls="DataTables_Table_0" class="form-select">
|
||||
<option value="${infoPrefix}Name">이름</option>
|
||||
<option value="${infoPrefix}ID">아이디</option>
|
||||
</select>
|
||||
<input id="term" autofocus type="text" placeholder="조회 조건을 입력하십시오." class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="search${infoPrefix}s();" class="btn btn-primary">찾기</button>
|
||||
<button onclick="${infoPrefix}Control.groups.newInfo();" class="btn btn-primary">+ 추가</button>
|
||||
<button id="btnRemove${infoPrefix}s" onclick="remove${infoPrefix}s();" class="btn btn-primary">- 제거</button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="datatables-ajax table table-bordered dataTable no-footer" id="DataTables_Table_0" aria-describedby="DataTables_Table_0_info">
|
||||
<thead>
|
||||
<tr><th tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" style="text-align:center;"><input onchange="${infoPrefix}Control.groups.select(this.checked);" type="checkbox" class="form-check-input"></th>
|
||||
<th class="sorting sorting_asc" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Full name: activate to sort column descending" style="">아이디</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Email: activate to sort column ascending" style="">이름</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Start date: activate to sort column ascending" style="">등록일자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="${infoPrefix}List">
|
||||
</tbody>
|
||||
<template id="${infoPrefix}Row">
|
||||
<tr data-key="{GRP_ID}">
|
||||
<td style="text-align:center;"><input value="{GRP_ID}" onchange="${infoPrefix}Control.groups.select('{GRP_ID}', this.checked);" type="checkbox" class="form-check-input"></td>
|
||||
<td onclick="${infoPrefix}Control.groups.setCurrent('{GRP_ID}')" ondblclick="${infoPrefix}Control.groups.getInfo({})">{GRP_ID}</td>
|
||||
<td onclick="${infoPrefix}Control.groups.setCurrent('{GRP_ID}')" ondblclick="${infoPrefix}Control.groups.getInfo({})">{GRP_NM}</td>
|
||||
<td onclick="${infoPrefix}Control.groups.setCurrent('{GRP_ID}')" ondblclick="${infoPrefix}Control.groups.getInfo({})">{REG_DT}</td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="${infoPrefix}NotFound">
|
||||
<tr class="odd">
|
||||
<td valign="top" colspan="4" class="dataTables_empty text-center">${prefixName} 정보를 찾지 못했습니다.</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
<div class="d-flex flex-row p-3 justify-content-between">
|
||||
<label id="${infoPrefix}PagingInfo" class="dataTables_info" role="status" aria-live="polite"></label>
|
||||
<ul id="${infoPrefix}Paging" class="pagination pagination-primary">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width:49%;">
|
||||
<h5 class="mt-3">기능 URL</h5>
|
||||
<div class="d-flex flex-row justify-content-end p-3">
|
||||
<div>
|
||||
<button id="btnAddActions" onclick="${infoPrefix}Control.addActions();" class="btn btn-primary">+ 추가</button>
|
||||
<button id="btnRemoveActions" onclick="removeActions();" class="btn btn-primary">- 제거</button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="datatables-ajax table table-bordered dataTable no-footer" id="DataTables_Table_0" aria-describedby="DataTables_Table_0_info">
|
||||
<thead>
|
||||
<tr><th tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" style="text-align:center;"><input id="actionToggler" onchange="${infoPrefix}Control.actions.select(this.checked);" type="checkbox" class="form-check-input"></th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Email: activate to sort column ascending" style="">기능 URL</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Start date: activate to sort column ascending" style="">등록일자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="actionList">
|
||||
</tbody>
|
||||
<template id="actionRow">
|
||||
<tr data-key="{GRP_ID}-{ACTION}">
|
||||
<td style="text-align:center;"><input value="{GRP_ID}-{ACTION}" onchange="${infoPrefix}Control.actions.select('{GRP_ID}-{ACTION}', this.checked);" type="checkbox" class="form-check-input"></td>
|
||||
<td onclick="${infoPrefix}Control.actions.setCurrent('{GRP_ID}-{ACTION}')">{ACTION}</td>
|
||||
<td onclick="${infoPrefix}Control.actions.setCurrent('{GRP_ID}-{ACTION}">{REG_DT}</td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="actionNotFound">
|
||||
<tr class="odd">
|
||||
<td valign="top" colspan="3" class="dataTables_empty text-center">기능 URL 정보를 찾지 못했습니다.</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
<div class="d-flex flex-row p-3 justify-content-between">
|
||||
<label id="actionPagingInfo" class="dataTables_info" role="status" aria-live="polite"></label>
|
||||
<ul id="actionPaging" class="pagination pagination-primary">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Page Body -->
|
||||
|
||||
<hr class="my-5" />
|
||||
</div>
|
||||
<!-- / Content -->
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/bottom.jsp" />
|
||||
|
||||
<div class="content-backdrop fade"></div>
|
||||
</div>
|
||||
<!-- Content wrapper -->
|
||||
</div>
|
||||
<!-- / Layout page -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Layout wrapper -->
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/tail.jsp" />
|
||||
<script src="<c:url value="/resources/js/base/actionGroup.js"/>" type="text/javascript"></script>
|
||||
<script >
|
||||
${functions}
|
||||
${userMenus}
|
||||
|
||||
let ${infoPrefix}Control = new ActionGroupControl();
|
||||
|
||||
function search${infoPrefix}s() {
|
||||
${infoPrefix}Control.groups.query = {
|
||||
by:$("#by").val(),
|
||||
term:$("#term").val()
|
||||
};
|
||||
${infoPrefix}Control.groups.load(1);
|
||||
}
|
||||
|
||||
function remove${infoPrefix}s() {
|
||||
dialog.alert({
|
||||
content:"선택한 ${prefixName} 정보를 제거하시겠습니까?",
|
||||
onOK:() => {
|
||||
${infoPrefix}Control.groups.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function removeActions() {
|
||||
dialog.alert({
|
||||
content:"선택한 기능 URL을 삭제하시겠습니까?",
|
||||
onOK:() => {
|
||||
${infoPrefix}Control.removeActions();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function render${infoPrefix}List() {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.groups.dataset;
|
||||
let empty = ${infoPrefix}List.empty;
|
||||
|
||||
let trs = empty ?
|
||||
[document.getElementById("${infoPrefix}NotFound").innerHTML] : <%-- from template#${infoPrefix}NotFound --%>
|
||||
${infoPrefix}List.inStrings(document.getElementById("${infoPrefix}Row").innerHTML); <%-- from template#${infoPrefix}Row --%>
|
||||
$("#${infoPrefix}List").html(trs.join());
|
||||
$("th input[type='checkbox']").prop("checked", false);
|
||||
}
|
||||
|
||||
${infoPrefix}Control.onGroupListChange = obj => {
|
||||
render${infoPrefix}List();
|
||||
|
||||
$("#${infoPrefix}Paging").setPaging({
|
||||
list:${infoPrefix}Control.groups.dataset,
|
||||
prefix:${infoPrefix}Control.groups.prefix,
|
||||
start:obj.${infoPrefix}Start,
|
||||
totalSize:obj.${infoPrefix}Total,
|
||||
fetchSize:obj.${infoPrefix}Fetch,
|
||||
func:"${infoPrefix}Control.groups.load({index})"
|
||||
});
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onCurrentGroupChange = item => {
|
||||
$("#btnAddActions").prop("disabled", !item);
|
||||
if (!item) return;
|
||||
|
||||
let key = item.data.GRP_ID;
|
||||
$("#${infoPrefix}List").setCurrentRow(key);
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onGroupSelect = selected => {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.groups.dataset;
|
||||
let keys = selected.map(e => ${infoPrefix}List.getKey(e));
|
||||
$("#${infoPrefix}List input[type='checkbox']").each(function() {
|
||||
let checkbox = $(this);
|
||||
checkbox.prop("checked", keys.includes(checkbox.val()));
|
||||
});
|
||||
|
||||
$("#btnRemove${infoPrefix}s").prop("disabled", keys.length < 1);
|
||||
};
|
||||
|
||||
|
||||
${infoPrefix}Control.onActionListChange = obj => {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.actions.dataset;
|
||||
let empty = ${infoPrefix}List.empty;
|
||||
|
||||
let trs = empty ?
|
||||
[document.getElementById("actionNotFound").innerHTML] : <%-- from template#${infoPrefix}NotFound --%>
|
||||
${infoPrefix}List.inStrings(document.getElementById("actionRow").innerHTML); <%-- from template#${infoPrefix}Row --%>
|
||||
$("#actionList").html(trs.join());
|
||||
$("#actionToggler").prop("checked", false);
|
||||
|
||||
$("#actionPaging").setPaging({
|
||||
list:${infoPrefix}Control.actions.dataset,
|
||||
prefix:${infoPrefix}Control.actions.prefix,
|
||||
start:obj.actionStart,
|
||||
totalSize:obj.actionTotal,
|
||||
fetchSize:obj.actionFetch,
|
||||
func:"${infoPrefix}Control.actions.load({index})"
|
||||
});
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onCurrentActionChange = item => {
|
||||
if (!item) return;
|
||||
|
||||
let data = item.data;
|
||||
let key = data.GRP_ID + "-" + data.ACTION;
|
||||
$("#actionList").setCurrentRow(key);
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onActionSelect = selected => {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.actions.dataset;
|
||||
let keys = selected.map(e => ${infoPrefix}List.getKey(e));
|
||||
$("#actionList input[type='checkbox']").each(function() {
|
||||
let checkbox = $(this);
|
||||
checkbox.prop("checked", keys.includes(checkbox.val()));
|
||||
});
|
||||
|
||||
$("#btnRemoveActions").prop("disabled", keys.length < 1);
|
||||
};
|
||||
|
||||
$("#term").onEnterPress(search${infoPrefix}s);
|
||||
|
||||
$(function(){
|
||||
${onload}
|
||||
${infoPrefix}Control.groups.setData({
|
||||
${infoPrefix}List:${groupList},
|
||||
${infoPrefix}Start:${groupStart},
|
||||
${infoPrefix}Fetch:${groupFetch},
|
||||
${infoPrefix}Total:${groupTotal}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,121 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<c:set var="prefixName" scope="request">기능 그룹</c:set>
|
||||
<!-- Page Body -->
|
||||
<div class="card">
|
||||
<div class="card-datatable text-nowrap">
|
||||
<div id="DataTables_Table_0_wrapper" class="dataTables_wrapper dt-bootstrap5 no-footer">
|
||||
<div class="d-flex flex-row justify-content-between p-3">
|
||||
<div>
|
||||
<div class="input-group" id="DataTables_Table_0_length">
|
||||
<select id="_groupBy" onchange="document.getElementById('_groupTerm').focus();" aria-controls="DataTables_Table_0" class="form-select">
|
||||
<option value="${infoPrefix}Name">이름</option>
|
||||
<option value="${infoPrefix}ID">아이디</option>
|
||||
</select>
|
||||
<input id="_groupTerm" autofocus type="text" placeholder="조회 조건을 입력하십시오." class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="search${infoPrefix}s();" class="btn btn-primary">찾기</button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="datatables-ajax table table-bordered dataTable no-footer" id="DataTables_Table_0" aria-describedby="DataTables_Table_0_info">
|
||||
<thead>
|
||||
<tr><th tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" style="text-align:center;"><input onchange="${infoPrefix}Control.groups.select(this.checked);" type="checkbox" class="form-check-input"></th>
|
||||
<th class="sorting sorting_asc" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Full name: activate to sort column descending" style="">아이디</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Email: activate to sort column ascending" style="">이름</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Start date: activate to sort column ascending" style="">등록일자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="${infoPrefix}List">
|
||||
</tbody>
|
||||
<template id="${infoPrefix}Row">
|
||||
<tr data-key="{GRP_ID}">
|
||||
<td style="text-align:center;"><input value="{GRP_ID}" onchange="${infoPrefix}Control.groups.select('{GRP_ID}', this.checked);" type="checkbox" class="form-check-input"></td>
|
||||
<td onclick="${infoPrefix}Control.groups.setCurrent('{GRP_ID}')" ondblclick="${infoPrefix}Control.groups.getInfo({})">{GRP_ID}</td>
|
||||
<td onclick="${infoPrefix}Control.groups.setCurrent('{GRP_ID}')" ondblclick="${infoPrefix}Control.groups.getInfo({})">{GRP_NM}</td>
|
||||
<td onclick="${infoPrefix}Control.groups.setCurrent('{GRP_ID}')" ondblclick="${infoPrefix}Control.groups.getInfo({})">{REG_DT}</td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="${infoPrefix}NotFound">
|
||||
<tr class="odd">
|
||||
<td valign="top" colspan="4" class="dataTables_empty text-center">${prefixName} 정보를 찾지 못했습니다.</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
<div class="d-flex flex-row p-3 justify-content-between">
|
||||
<label id="${infoPrefix}PagingInfo" class="dataTables_info" role="status" aria-live="polite"></label>
|
||||
<ul id="${infoPrefix}Paging" class="pagination pagination-primary">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Page Body -->
|
||||
<script >
|
||||
var ${infoPrefix}Control = new ActionGroupControl(false);
|
||||
|
||||
function getSelectedActionGroup() {
|
||||
let selected = ${infoPrefix}Control.groups.dataset.getKeys("selected");
|
||||
if (selected.length < 1)
|
||||
return dialog.alert("기능그룹을 선택하십시오.");
|
||||
else
|
||||
return selected;
|
||||
}
|
||||
|
||||
function search${infoPrefix}s() {
|
||||
${infoPrefix}Control.groups.query = {
|
||||
by:$("#_groupBy").val(),
|
||||
term:$("#_groupTerm").val()
|
||||
};
|
||||
${infoPrefix}Control.groups.load(1);
|
||||
}
|
||||
|
||||
${infoPrefix}Control.onGroupListChange = obj => {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.groups.dataset;
|
||||
let empty = ${infoPrefix}List.empty;
|
||||
|
||||
let trs = empty ?
|
||||
[document.getElementById("${infoPrefix}NotFound").innerHTML] : <%-- from template#${infoPrefix}NotFound --%>
|
||||
${infoPrefix}List.inStrings(document.getElementById("${infoPrefix}Row").innerHTML); <%-- from template#${infoPrefix}Row --%>
|
||||
$("#${infoPrefix}List").html(trs.join());
|
||||
$("th input[type='checkbox']").prop("checked", false);
|
||||
|
||||
$("#${infoPrefix}Paging").setPaging({
|
||||
list:${infoPrefix}Control.groups.dataset,
|
||||
prefix:${infoPrefix}Control.groups.prefix,
|
||||
start:obj.${infoPrefix}Start,
|
||||
totalSize:obj.${infoPrefix}Total,
|
||||
fetchSize:obj.${infoPrefix}Fetch,
|
||||
func:"${infoPrefix}Control.groups.load({index})"
|
||||
});
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onCurrentGroupChange = item => {
|
||||
if (!item) return;
|
||||
|
||||
let key = item.data.GRP_ID;
|
||||
$("#${infoPrefix}List").setCurrentRow(key);
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onGroupSelect = selected => {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.groups.dataset;
|
||||
let keys = selected.map(e => ${infoPrefix}List.getKey(e));
|
||||
$("#${infoPrefix}List input[type='checkbox']").each(function() {
|
||||
let checkbox = $(this);
|
||||
checkbox.prop("checked", keys.includes(checkbox.val()));
|
||||
});
|
||||
};
|
||||
|
||||
$("#_groupTerm").onEnterPress(search${infoPrefix}s);
|
||||
|
||||
$(function(){
|
||||
${onload}
|
||||
${infoPrefix}Control.groups.setData({
|
||||
${infoPrefix}List:${groupList},
|
||||
${infoPrefix}Start:${groupStart},
|
||||
${infoPrefix}Fetch:${groupFetch},
|
||||
${infoPrefix}Total:${groupTotal}
|
||||
});
|
||||
});
|
||||
</script>
|
@ -0,0 +1,91 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<div class="d-flex flex-row justify-content-end p-3">
|
||||
<div>
|
||||
<button id="btnAddActions" onclick="${infoPrefix}Control.addActions();" class="btn btn-primary">+ 추가</button>
|
||||
<button id="btnRemoveActions" onclick="removeActions();" class="btn btn-primary">- 제거</button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="datatables-ajax table table-bordered dataTable no-footer" id="DataTables_Table_0" aria-describedby="DataTables_Table_0_info">
|
||||
<thead>
|
||||
<tr><th tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" style="text-align:center;"><input id="actionToggler" onchange="${infoPrefix}Control.actions.select(this.checked);" type="checkbox" class="form-check-input"></th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Email: activate to sort column ascending" style="">기능 그룹</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Start date: activate to sort column ascending" style="">등록일자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="actionList">
|
||||
</tbody>
|
||||
<template id="actionRow">
|
||||
<tr data-key="{AUTH_ID}-{GRP_ID}">
|
||||
<td style="text-align:center;"><input value="{AUTH_ID}-{GRP_ID}" onchange="${infoPrefix}Control.actions.select('{AUTH_ID}-{GRP_ID}', this.checked);" type="checkbox" class="form-check-input"></td>
|
||||
<td onclick="${infoPrefix}Control.actions.setCurrent('{AUTH_ID}-{GRP_ID}')">{GRP_ID}</td>
|
||||
<td onclick="${infoPrefix}Control.actions.setCurrent('{AUTH_ID}-{GRP_ID}">{REG_DT}</td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="actionNotFound">
|
||||
<tr class="odd">
|
||||
<td valign="top" colspan="3" class="dataTables_empty text-center">기능 그룹 정보를 찾지 못했습니다.</td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="adminActions">
|
||||
<tr class="odd">
|
||||
<td valign="top" colspan="3" class="dataTables_empty text-center">{authority}는 모든 기능을 사용할 수 있습니다.</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
<div class="d-flex flex-row p-3 justify-content-between">
|
||||
<label id="actionPagingInfo" class="dataTables_info" role="status" aria-live="polite"></label>
|
||||
<ul id="actionPaging" class="pagination pagination-primary">
|
||||
</ul>
|
||||
</div>
|
||||
<c:set var="actionGroupFunc" scope="request">function removeActions() {
|
||||
dialog.alert({
|
||||
content:"선택한 기능그룹을 삭제하시겠습니까?",
|
||||
onOK:() => {
|
||||
${infoPrefix}Control.removeActions();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
${infoPrefix}Control.onActionListChange = obj => {
|
||||
let authority = ${infoPrefix}Control.authorities.getCurrent();
|
||||
authority = authority ? authority.AUTH_NM : "";
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.actions.dataset;
|
||||
let empty = ${infoPrefix}List.empty;
|
||||
|
||||
let trs =
|
||||
${infoPrefix}Control.authorities.isAdmin() ? [document.getElementById("adminActions").innerHTML.replace(/{authority}/, authority)] :
|
||||
empty ?
|
||||
[document.getElementById("actionNotFound").innerHTML] : <%-- from template#${infoPrefix}NotFound --%>
|
||||
${infoPrefix}List.inStrings(document.getElementById("actionRow").innerHTML); <%-- from template#${infoPrefix}Row --%>
|
||||
$("#actionList").html(trs.join());
|
||||
$("#actionToggler").prop("checked", false);
|
||||
|
||||
$("#actionPaging").setPaging({
|
||||
list:${infoPrefix}Control.actions.dataset,
|
||||
prefix:${infoPrefix}Control.actions.prefix,
|
||||
start:obj.actionStart,
|
||||
totalSize:obj.actionTotal,
|
||||
fetchSize:obj.actionFetch,
|
||||
func:"${infoPrefix}Control.actions.load({index})"
|
||||
});
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onCurrentActionChange = item => {
|
||||
if (!item) return;
|
||||
|
||||
let data = item.data;
|
||||
let key = data.AUTH_ID + "-" + data.GRP_ID;
|
||||
$("#actionList").setCurrentRow(key);
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onActionSelect = selected => {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.actions.dataset;
|
||||
let keys = selected.map(e => ${infoPrefix}List.getKey(e));
|
||||
$("#actionList input[type='checkbox']").each(function() {
|
||||
let checkbox = $(this);
|
||||
checkbox.prop("checked", keys.includes(checkbox.val()));
|
||||
});
|
||||
|
||||
$("#btnRemoveActions").prop("disabled", keys.length < 1);
|
||||
};</c:set>
|
@ -0,0 +1,82 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<form id="infoPrefix-form">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="id"
|
||||
>아이디</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="id" type="text" required data-map="AUTH_ID" maxlength="50" class="form-control" placeholder="prefixName 아이디" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="name"
|
||||
>이름</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="name" type="text" required data-map="AUTH_NM" maxlength="60" class="form-control" placeholder="prefixName 이름" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="description"
|
||||
>설명</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="description" type="text" data-map="DSCRP" maxlength="200" class="form-control dob-picker" placeholder="prefixName 설명"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4 justify-content-end">
|
||||
<div class="col-sm-12" style="text-align:right;">
|
||||
<button id="btnSaveAuth" onclick="saveinfoPrefix();" type="button" class="btn btn-primary">저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
|
||||
var infoPrefixFields = new FormFields("#infoPrefix-form");
|
||||
|
||||
infoPrefixControl.authorities.setInfo = obj => {
|
||||
infoPrefixFields.set(obj);
|
||||
let info = obj.data;
|
||||
let create = isEmpty(info.AUTH_ID);
|
||||
$("input[name='id']").prop("readonly", !create);
|
||||
$("#infoPrefix-form input")
|
||||
.change(function() {
|
||||
let input = $(this),
|
||||
name = input.attr("data-map"),
|
||||
val = input.val();
|
||||
infoPrefixControl.authorities.setValue(name, val);
|
||||
})
|
||||
.onEnterPress(saveinfoPrefix);
|
||||
|
||||
$("input[name='" + (create ? "id" : "name") + "']").focus();
|
||||
$("#btnSaveAuth").prop("disabled", infoPrefixControl.authorities.isBuiltIn(info));
|
||||
}
|
||||
|
||||
infoPrefixControl.authorities.onModify = (changed) => {
|
||||
if (["AUTH_NM"].filter(e => changed.includes(e)).length < 1)
|
||||
return;
|
||||
|
||||
renderinfoPrefixList();
|
||||
infoPrefixControl.authorities.dataset.setState();
|
||||
}
|
||||
|
||||
function saveinfoPrefix() {
|
||||
if (!$("#infoPrefix-form input").validInputs()) return;
|
||||
|
||||
dialog.alert({
|
||||
content:"현재 prefixName 정보를 저장하시겠습니까?",
|
||||
onOK:() => {
|
||||
infoPrefixControl.authorities.save(infoPrefixFields.get());
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceURL=actionGroup-info.jsp
|
||||
</script>
|
@ -0,0 +1,207 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<jsp:include page="/WEB-INF/jsp/include/head.jsp" />
|
||||
<body>
|
||||
<!-- Layout wrapper -->
|
||||
<div class="layout-wrapper layout-content-navbar">
|
||||
<div class="layout-container">
|
||||
<jsp:include page="/WEB-INF/jsp/include/userMenus.jsp" />
|
||||
<!-- Layout container -->
|
||||
<!-- Layout page -->
|
||||
<div class="layout-page">
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/top.jsp" />
|
||||
|
||||
<!-- Content wrapper -->
|
||||
<div class="content-wrapper">
|
||||
<!-- Content -->
|
||||
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<%--h4 id="pageTitle" class="fw-bold py-3 mb-4">페이지 제목</h4--%>
|
||||
<c:set var="prefixName" scope="request">권한</c:set>
|
||||
<!-- Page Body -->
|
||||
<div class="card">
|
||||
<div class="card-datatable text-nowrap">
|
||||
<div id="DataTables_Table_0_wrapper" class="dataTables_wrapper dt-bootstrap5 no-footer">
|
||||
|
||||
<div class="d-flex flex-row justify-content-evenly">
|
||||
<div style="width:49%;">
|
||||
<h5 class="mt-3">권한</h5>
|
||||
<div class="d-flex flex-row justify-content-between p-3">
|
||||
<div>
|
||||
<div class="input-group" id="DataTables_Table_0_length">
|
||||
<select id="by" onchange="document.getElementById('term').focus();" aria-controls="DataTables_Table_0" class="form-select">
|
||||
<option value="authName">이름</option>
|
||||
<option value="authID">아이디</option>
|
||||
</select>
|
||||
<input id="term" autofocus type="text" placeholder="조회 조건을 입력하십시오." class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="search${infoPrefix}s();" class="btn btn-primary">찾기</button>
|
||||
<button onclick="${infoPrefix}Control.authorities.newInfo();" class="btn btn-primary">+ 추가</button>
|
||||
<button id="btnRemove${infoPrefix}s" onclick="remove${infoPrefix}s();" class="btn btn-primary">- 제거</button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="datatables-ajax table table-bordered dataTable no-footer" id="DataTables_Table_0" aria-describedby="DataTables_Table_0_info">
|
||||
<thead>
|
||||
<tr><th tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" style="text-align:center;"><input onchange="${infoPrefix}Control.authorities.select(this.checked);" type="checkbox" class="form-check-input"></th>
|
||||
<th class="sorting sorting_asc" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Full name: activate to sort column descending" style="">아이디</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Email: activate to sort column ascending" style="">이름</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Start date: activate to sort column ascending" style="">등록일자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="${infoPrefix}List">
|
||||
</tbody>
|
||||
<template id="${infoPrefix}Row">
|
||||
<tr data-key="{AUTH_ID}">
|
||||
<td style="text-align:center;"><input value="{AUTH_ID}" onchange="${infoPrefix}Control.authorities.select('{AUTH_ID}', this.checked);" type="checkbox" class="form-check-input"></td>
|
||||
<td onclick="${infoPrefix}Control.authorities.setCurrent('{AUTH_ID}')" ondblclick="${infoPrefix}Control.authorities.getInfo({})">{AUTH_ID}</td>
|
||||
<td onclick="${infoPrefix}Control.authorities.setCurrent('{AUTH_ID}')" ondblclick="${infoPrefix}Control.authorities.getInfo({})">{AUTH_NM}</td>
|
||||
<td onclick="${infoPrefix}Control.authorities.setCurrent('{AUTH_ID}')" ondblclick="${infoPrefix}Control.authorities.getInfo({})">{REG_DT}</td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="${infoPrefix}NotFound">
|
||||
<tr class="odd">
|
||||
<td valign="top" colspan="4" class="dataTables_empty text-center">${prefixName} 정보를 찾지 못했습니다.</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
<div class="d-flex flex-row p-3 justify-content-between">
|
||||
<label id="${infoPrefix}PagingInfo" class="dataTables_info" role="status" aria-live="polite"></label>
|
||||
<ul id="${infoPrefix}Paging" class="pagination pagination-primary">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width:49%; padding-top:.25em;">
|
||||
<div class="nav-align-top">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item">
|
||||
<button type="button" onClick="${infoPrefix}Control.getLinkedList('users');" class="nav-link active" role="tab" data-bs-toggle="tab" data-bs-target="#navs-top-users" aria-controls="navs-top-users" aria-selected="true">사용자</button>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button type="button" onClick="${infoPrefix}Control.getLinkedList('actions');" class="nav-link" role="tab" data-bs-toggle="tab" data-bs-target="#navs-top-actions" aria-controls="navs-top-actions" aria-selected="false">기능그룹</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content" style="padding:.6em 0;">
|
||||
<div class="tab-pane fade show active" id="navs-top-users" role="tabpanel">
|
||||
<jsp:include page="user-list.jsp" />
|
||||
</div>
|
||||
<div class="tab-pane fade" id="navs-top-actions" role="tabpanel">
|
||||
<jsp:include page="actionGroup-list.jsp" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Page Body -->
|
||||
|
||||
<hr class="my-5" />
|
||||
</div>
|
||||
<!-- / Content -->
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/bottom.jsp" />
|
||||
|
||||
<div class="content-backdrop fade"></div>
|
||||
</div>
|
||||
<!-- Content wrapper -->
|
||||
</div>
|
||||
<!-- / Layout page -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Layout wrapper -->
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/tail.jsp" />
|
||||
<script src="<c:url value="/resources/js/base/user.js?${ver}"/>"></script>
|
||||
<script src="<c:url value="/resources/js/base/actionGroup.js?${ver}"/>"></script>
|
||||
<script src="<c:url value="/resources/js/base/authority.js?${ver}"/>"></script>
|
||||
<script >
|
||||
${functions}
|
||||
${userMenus}
|
||||
|
||||
let ${infoPrefix}Control = new AuthorityControl();
|
||||
|
||||
function search${infoPrefix}s() {
|
||||
${infoPrefix}Control.authorities.query = {
|
||||
by:$("#by").val(),
|
||||
term:$("#term").val()
|
||||
};
|
||||
${infoPrefix}Control.authorities.load(1);
|
||||
}
|
||||
|
||||
function remove${infoPrefix}s() {
|
||||
dialog.alert({
|
||||
content:"선택한 ${prefixName} 정보를 제거하시겠습니까?",
|
||||
onOK:() => {
|
||||
${infoPrefix}Control.removeAuthorities();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function render${infoPrefix}List() {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.authorities.dataset;
|
||||
let empty = ${infoPrefix}List.empty;
|
||||
|
||||
let trs = empty ?
|
||||
[document.getElementById("${infoPrefix}NotFound").innerHTML] : <%-- from template#${infoPrefix}NotFound --%>
|
||||
${infoPrefix}List.inStrings(document.getElementById("${infoPrefix}Row").innerHTML); <%-- from template#${infoPrefix}Row --%>
|
||||
$("#${infoPrefix}List").html(trs.join());
|
||||
$("th input[type='checkbox']").prop("checked", false);
|
||||
}
|
||||
|
||||
${infoPrefix}Control.onAuthorityListChange = obj => {
|
||||
render${infoPrefix}List();
|
||||
|
||||
$("#${infoPrefix}Paging").setPaging({
|
||||
list:${infoPrefix}Control.authorities.dataset,
|
||||
prefix:${infoPrefix}Control.authorities.prefix,
|
||||
start:obj.${infoPrefix}Start,
|
||||
totalSize:obj.${infoPrefix}Total,
|
||||
fetchSize:obj.${infoPrefix}Fetch,
|
||||
func:"${infoPrefix}Control.authorities.load({index})"
|
||||
});
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onCurrentAuthorityChange = item => {
|
||||
$("#btnAddActions").prop("disabled", !item || ${infoPrefix}Control.authorities.isAdmin(item.data));
|
||||
$("#btnAddUsers").prop("disabled", !item || ${infoPrefix}Control.authorities.isImplicit(item.data));
|
||||
if (!item) return;
|
||||
|
||||
let key = item.data.AUTH_ID;
|
||||
$("#${infoPrefix}List").setCurrentRow(key);
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onAuthoritySelect = selected => {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.authorities.dataset;
|
||||
let keys = selected.map(e => ${infoPrefix}List.getKey(e));
|
||||
$("#${infoPrefix}List input[type='checkbox']").each(function() {
|
||||
let checkbox = $(this);
|
||||
checkbox.prop("checked", keys.includes(checkbox.val()));
|
||||
});
|
||||
|
||||
let builtIn = selected.filter(info => ${infoPrefix}Control.authorities.isBuiltIn(info)).length > 0;
|
||||
|
||||
$("#btnRemove${infoPrefix}s").prop("disabled", keys.length < 1 || builtIn);
|
||||
};
|
||||
|
||||
${userFunc}
|
||||
${actionGroupFunc}
|
||||
|
||||
$("#term").onEnterPress(search${infoPrefix}s);
|
||||
|
||||
$(function(){
|
||||
${onload}
|
||||
${infoPrefix}Control.authorities.setData({
|
||||
${infoPrefix}List:${authorityList},
|
||||
${infoPrefix}Start:${authorityStart},
|
||||
${infoPrefix}Fetch:${authorityFetch},
|
||||
${infoPrefix}Total:${authorityTotal}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,91 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<div class="d-flex flex-row justify-content-end p-3">
|
||||
<div>
|
||||
<button id="btnAddUsers" onclick="${infoPrefix}Control.addUsers();" class="btn btn-primary">+ 추가</button>
|
||||
<button id="btnRemoveUsers" onclick="removeUsers();" class="btn btn-primary">- 제거</button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="datatables-ajax table table-bordered dataTable no-footer" id="DataTables_Table_0" aria-describedby="DataTables_Table_0_info">
|
||||
<thead>
|
||||
<tr><th tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" style="text-align:center;"><input id="userToggler" onchange="${infoPrefix}Control.users.select(this.checked);" type="checkbox" class="form-check-input"></th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Email: activate to sort column ascending" style="">사용자</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Start date: activate to sort column ascending" style="">등록일자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="userList">
|
||||
</tbody>
|
||||
<template id="userRow">
|
||||
<tr data-key="{AUTH_ID}-{USER_ID}">
|
||||
<td style="text-align:center;"><input value="{AUTH_ID}-{USER_ID}" onchange="${infoPrefix}Control.users.select('{AUTH_ID}-{USER_ID}', this.checked);" type="checkbox" class="form-check-input"></td>
|
||||
<td onclick="${infoPrefix}Control.users.setCurrent('{AUTH_ID}-{USER_ID}')">{USER_ID}</td>
|
||||
<td onclick="${infoPrefix}Control.users.setCurrent('{AUTH_ID}-{USER_ID}">{REG_DT}</td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="userNotFound">
|
||||
<tr class="odd">
|
||||
<td valign="top" colspan="3" class="dataTables_empty text-center">사용자 정보를 찾지 못했습니다.</td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="implicitActions">
|
||||
<tr class="odd">
|
||||
<td valign="top" colspan="3" class="dataTables_empty text-center">{authority}는 사용자를 지정하지 않습니다.</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
<div class="d-flex flex-row p-3 justify-content-between">
|
||||
<label id="userPagingInfo" class="dataTables_info" role="status" aria-live="polite"></label>
|
||||
<ul id="userPaging" class="pagination pagination-primary">
|
||||
</ul>
|
||||
</div>
|
||||
<c:set var="userFunc" scope="request">
|
||||
function removeUsers() {
|
||||
dialog.alert({
|
||||
content:"선택한 사용자를 삭제하시겠습니까?",
|
||||
onOK:() => {
|
||||
${infoPrefix}Control.removeUsers();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
${infoPrefix}Control.onUserListChange = obj => {
|
||||
let authority = ${infoPrefix}Control.authorities.getCurrent();
|
||||
authority = authority ? authority.AUTH_NM : "";
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.users.dataset;
|
||||
let empty = ${infoPrefix}List.empty;
|
||||
|
||||
let trs =
|
||||
${infoPrefix}Control.authorities.isImplicit() ? [document.getElementById("implicitActions").innerHTML.replace(/{authority}/, authority)] :
|
||||
empty ? [document.getElementById("userNotFound").innerHTML] : <%-- from template#${infoPrefix}NotFound --%>
|
||||
${infoPrefix}List.inStrings(document.getElementById("userRow").innerHTML); <%-- from template#${infoPrefix}Row --%>
|
||||
$("#userList").html(trs.join());
|
||||
$("#userToggler").prop("checked", false);
|
||||
|
||||
$("#userPaging").setPaging({
|
||||
list:${infoPrefix}Control.users.dataset,
|
||||
prefix:${infoPrefix}Control.users.prefix,
|
||||
start:obj.userStart,
|
||||
totalSize:obj.userTotal,
|
||||
fetchSize:obj.userFetch,
|
||||
func:"${infoPrefix}Control.users.load({index})"
|
||||
});
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onCurrentUserChange = item => {
|
||||
if (!item) return;
|
||||
|
||||
let data = item.data;
|
||||
let key = data.AUTH_ID + "-" + data.USER_ID;
|
||||
$("#userList").setCurrentRow(key);
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onUserSelect = selected => {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.users.dataset;
|
||||
let keys = selected.map(e => ${infoPrefix}List.getKey(e));
|
||||
$("#userList input[type='checkbox']").each(function() {
|
||||
let checkbox = $(this);
|
||||
checkbox.prop("checked", keys.includes(checkbox.val()));
|
||||
});
|
||||
|
||||
$("#btnRemoveUsers").prop("disabled", keys.length < 1);
|
||||
};</c:set>
|
@ -0,0 +1,142 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<form id="code-form">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="code"
|
||||
>코드</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="code" type="text" required data-map="CODE" maxlength="15" class="form-control" placeholder="코드" />
|
||||
<input name="groupID" type="hidden" data-map="GRP_ID" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="value"
|
||||
>코드값</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="value" type="text" required data-map="CODE_VAL" maxlength="60" class="form-control" placeholder="코드값" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="description"
|
||||
>설명</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="description" type="text" data-map="DSCRP" maxlength="200" class="form-control" placeholder="코드 설명"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="etc1"
|
||||
>기타값 1</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="etc1" type="text" data-map="ETC1" maxlength="200" class="form-control" placeholder="기타값 1"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="etc2"
|
||||
>기타값2</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="etc2" type="text" data-map="ETC2" maxlength="200" class="form-control" placeholder="기타값 2"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="etc3"
|
||||
>기타값3</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="etc3" type="text" data-map="ET3" maxlength="200" class="form-control" placeholder="기타값 3"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="createdBy"
|
||||
>등록자</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" data-map="RGTR" readonly class="form-control" placeholder="등록자"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="description"
|
||||
>등록일자</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" data-map="REG_DT" readonly class="form-control" placeholder="등록일자"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="description"
|
||||
>사용여부</label
|
||||
>
|
||||
<div class="col-sm-10" style="padding:.5em .7em;">
|
||||
<span id="codeInUse"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4 justify-content-end">
|
||||
<div class="col-sm-12" style="text-align:right;">
|
||||
<button onclick="saveCode();" type="button" class="btn btn-primary">저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
|
||||
var codeFields = new FormFields("#code-form");
|
||||
|
||||
codeControl.codes.setInfo = obj => {
|
||||
let info = obj.data;
|
||||
codeFields.set(obj);
|
||||
let create = isEmpty(info.CODE);
|
||||
$("input[name='code']").prop("readonly", !create);
|
||||
$("#code-form input")
|
||||
.change(function() {
|
||||
let input = $(this),
|
||||
name = input.attr("data-map"),
|
||||
val = input.val();
|
||||
codeControl.codes.setValue(name, val);
|
||||
})
|
||||
.onEnterPress(saveCode);
|
||||
$("#codeInUse").html("Y" == info.USE_YN ? "사용 중" : "사용하지 않음");
|
||||
document.querySelector("input[name='" + (create ? "code" : "value") + "']").focus();
|
||||
}
|
||||
|
||||
codeControl.codes.onModify = (changed) => {
|
||||
if (["CODE", "CODE_VAL"].filter(e => changed.includes(e)).length < 1)
|
||||
return;
|
||||
|
||||
renderCodeList();
|
||||
codeControl.codes.dataset.setState();
|
||||
}
|
||||
|
||||
function saveCode() {
|
||||
if (!$("#code-form input").validInputs()) return;
|
||||
|
||||
dialog.alert({
|
||||
content:"현재 코드 정보를 저장하시겠습니까?",
|
||||
onOK:() => {
|
||||
codeControl.codes.save(codeFields.get());
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceURL=code-info.jsp
|
||||
</script>
|
@ -0,0 +1,269 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<jsp:include page="/WEB-INF/jsp/include/head.jsp" />
|
||||
<body>
|
||||
<!-- Layout wrapper -->
|
||||
<div class="layout-wrapper layout-content-navbar">
|
||||
<div class="layout-container">
|
||||
<jsp:include page="/WEB-INF/jsp/include/userMenus.jsp" />
|
||||
<!-- Layout container -->
|
||||
<!-- Layout page -->
|
||||
<div class="layout-page">
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/top.jsp" />
|
||||
|
||||
<!-- Content wrapper -->
|
||||
<div class="content-wrapper">
|
||||
<!-- Content -->
|
||||
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<%--h4 id="pageTitle" class="fw-bold py-3 mb-4">페이지 제목</h4--%>
|
||||
<c:set var="prefixName" scope="request">코드 그룹</c:set>
|
||||
<!-- Page Body -->
|
||||
<div class="card">
|
||||
<div class="card-datatable text-nowrap">
|
||||
<div id="DataTables_Table_0_wrapper" class="dataTables_wrapper dt-bootstrap5 no-footer">
|
||||
|
||||
<div class="d-flex flex-row justify-content-evenly">
|
||||
<div style="width:49%;">
|
||||
<h5 class="mt-3">${prefixName}</h5>
|
||||
<div class="d-flex flex-row justify-content-between p-3">
|
||||
<%--div>
|
||||
<div class="input-group" id="DataTables_Table_0_length">
|
||||
<select id="by" onchange="document.getElementById('term').focus();" aria-controls="DataTables_Table_0" class="form-select">
|
||||
<option value="groupName">이름</option>
|
||||
<option value="groupID">아이디</option>
|
||||
</select>
|
||||
<input id="term" autofocus type="text" placeholder="조회 조건을 입력하십시오." class="form-control">
|
||||
</div>
|
||||
</div--%>
|
||||
<div>
|
||||
<%--button onclick="searchGroups();" class="btn btn-primary">찾기</button--%>
|
||||
<button onclick="codeControl.groups.newInfo();" class="btn btn-primary">+ 추가</button>
|
||||
<button id="btnRemoveGroups" onclick="removeGroups();" class="btn btn-primary">- 제거</button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="datatables-ajax table table-bordered dataTable no-footer" id="DataTables_Table_0" aria-describedby="DataTables_Table_0_info">
|
||||
<thead>
|
||||
<tr><th tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" style="text-align:center;"><input onchange="codeControl.groups.select(this.checked);" type="checkbox" class="form-check-input"></th>
|
||||
<th class="sorting sorting_asc" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Full name: activate to sort column descending">아이디</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Email: activate to sort column ascending">이름</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Start date: activate to sort column ascending">등록일자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="groupList">
|
||||
</tbody>
|
||||
<template id="groupRow">
|
||||
<tr data-key="{GRP_ID}">
|
||||
<td style="text-align:center;"><input value="{GRP_ID}" onchange="codeControl.groups.select('{GRP_ID}', this.checked);" type="checkbox" class="form-check-input"></td>
|
||||
<td onclick="codeControl.groups.setCurrent('{GRP_ID}')" ondblclick="codeControl.groups.getInfo({})">{GRP_ID}</td>
|
||||
<td onclick="codeControl.groups.setCurrent('{GRP_ID}')" ondblclick="codeControl.groups.getInfo({})">{GRP_NM}</td>
|
||||
<td onclick="codeControl.groups.setCurrent('{GRP_ID}')" ondblclick="codeControl.groups.getInfo({})">{REG_DT}</td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="groupNotFound">
|
||||
<tr class="odd">
|
||||
<td valign="top" colspan="4" class="dataTables_empty text-center">${prefixName} 정보를 찾지 못했습니다.</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
<div class="d-flex flex-row p-3 justify-content-between">
|
||||
<label id="groupPagingInfo" class="dataTables_info" role="status" aria-live="polite"></label>
|
||||
<ul id="groupPaging" class="pagination pagination-primary">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width:49%;">
|
||||
<h5 class="mt-3">공통 코드</h5>
|
||||
<div class="d-flex flex-row justify-content-end p-3">
|
||||
<div>
|
||||
<button id="btnAddCode" onclick="codeControl.newCode();" class="btn btn-primary">+ 추가</button>
|
||||
<button id="btnRemoveCodes" onclick="removeCodes();" class="btn btn-primary">- 제거</button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="datatables-ajax table table-bordered dataTable no-footer" id="DataTables_Table_0" aria-describedby="DataTables_Table_0_info">
|
||||
<thead>
|
||||
<tr><th tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" style="text-align:center;"><input id="codeToggler" onchange="codeControl.codes.select(this.checked);" type="checkbox" class="form-check-input"></th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Email: activate to sort column ascending">코드</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Email: activate to sort column ascending">코드값</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Start date: activate to sort column ascending">등록일자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="codeList">
|
||||
</tbody>
|
||||
<template id="codeRow">
|
||||
<tr data-key="{CODE}">
|
||||
<td style="text-align:center;"><input value="{CODE}" onchange="codeControl.codes.select('{CODE}', this.checked);" type="checkbox" class="form-check-input"></td>
|
||||
<td onclick="codeControl.codes.setCurrent('{CODE}')" ondblclick="codeControl.codes.getInfo({})">{CODE}</td>
|
||||
<td onclick="codeControl.codes.setCurrent('{CODE}')" ondblclick="codeControl.codes.getInfo({})">{CODE_VAL}</td>
|
||||
<td onclick="codeControl.codes.setCurrent('{CODE}')" ondblclick="codeControl.codes.getInfo({})">{REG_DT}</td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="codeNotFound">
|
||||
<tr class="odd">
|
||||
<td valign="top" colspan="4" class="dataTables_empty text-center">코드 정보를 찾지 못했습니다.</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
<div class="d-flex flex-row p-3 justify-content-between">
|
||||
<label id="codePagingInfo" class="dataTables_info" role="status" aria-live="polite"></label>
|
||||
<ul id="codePaging" class="pagination pagination-primary">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Page Body -->
|
||||
|
||||
<hr class="my-5" />
|
||||
</div>
|
||||
<!-- / Content -->
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/bottom.jsp" />
|
||||
|
||||
<div class="content-backdrop fade"></div>
|
||||
</div>
|
||||
<!-- Content wrapper -->
|
||||
</div>
|
||||
<!-- / Layout page -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Layout wrapper -->
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/tail.jsp" />
|
||||
<script src="<c:url value="/resources/js/base/code.js"/>?${ver}"></script>
|
||||
<script >
|
||||
${functions}
|
||||
${userMenus}
|
||||
|
||||
let codeControl = new CodeControl();
|
||||
|
||||
function searchGroups() {
|
||||
codeControl.groups.query = {
|
||||
by:$("#by").val(),
|
||||
term:$("#term").val()
|
||||
};
|
||||
codeControl.groups.load(1);
|
||||
}
|
||||
|
||||
function removeGroups() {
|
||||
dialog.alert({
|
||||
content:"선택한 ${prefixName} 정보를 제거하시겠습니까?",
|
||||
onOK:() => {
|
||||
codeControl.groups.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function removeCodes() {
|
||||
dialog.alert({
|
||||
content:"선택한 코드를 삭제하시겠습니까?",
|
||||
onOK:() => {
|
||||
codeControl.removeCodes();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function renderGroupList() {
|
||||
let groupList = codeControl.groups.dataset;
|
||||
let empty = groupList.empty;
|
||||
|
||||
let trs = empty ?
|
||||
[document.getElementById("groupNotFound").innerHTML] : <%-- from template#groupNotFound --%>
|
||||
groupList.inStrings(document.getElementById("groupRow").innerHTML); <%-- from template#groupRow --%>
|
||||
$("#groupList").html(trs.join());
|
||||
$("th input[type='checkbox']").prop("checked", false);
|
||||
}
|
||||
|
||||
codeControl.onGroupListChange = obj => {
|
||||
renderGroupList();
|
||||
|
||||
$("#groupPaging").setPaging({
|
||||
list:codeControl.groups.dataset,
|
||||
prefix:codeControl.groups.prefix,
|
||||
start:obj.groupStart,
|
||||
totalSize:obj.groupTotal,
|
||||
fetchSize:obj.groupFetch,
|
||||
func:"codeControl.groups.load({index})"
|
||||
});
|
||||
};
|
||||
|
||||
codeControl.onCurrentGroupChange = item => {
|
||||
$("#btnAddCode").prop("disabled", !item);
|
||||
if (!item) return;
|
||||
|
||||
let key = item.data.GRP_ID;
|
||||
$("#groupList").setCurrentRow(key);
|
||||
};
|
||||
|
||||
codeControl.onGroupSelect = selected => {
|
||||
let groupList = codeControl.groups.dataset;
|
||||
let keys = selected.map(e => groupList.getKey(e));
|
||||
$("#groupList input[type='checkbox']").each(function() {
|
||||
let checkbox = $(this);
|
||||
checkbox.prop("checked", keys.includes(checkbox.val()));
|
||||
});
|
||||
|
||||
$("#btnRemoveGroups").prop("disabled", keys.length < 1);
|
||||
};
|
||||
|
||||
function renderCodeList() {
|
||||
let codeList = codeControl.codes.dataset;
|
||||
let empty = codeList.empty;
|
||||
|
||||
let trs = empty ?
|
||||
[document.getElementById("codeNotFound").innerHTML] : <%-- from template#groupNotFound --%>
|
||||
codeList.inStrings(document.getElementById("codeRow").innerHTML); <%-- from template#groupRow --%>
|
||||
$("#codeList").html(trs.join());
|
||||
$("#codeToggler").prop("checked", false);
|
||||
}
|
||||
|
||||
codeControl.onCodeListChange = obj => {
|
||||
renderCodeList();
|
||||
|
||||
$("#codePaging").setPaging({
|
||||
list:codeControl.codes.dataset,
|
||||
prefix:codeControl.codes.prefix,
|
||||
start:obj.codeStart,
|
||||
totalSize:obj.codeTotal,
|
||||
fetchSize:obj.codeFetch,
|
||||
func:"codeControl.codes.load({index})"
|
||||
});
|
||||
};
|
||||
|
||||
codeControl.onCurrentCodeChange = item => {
|
||||
if (!item) return;
|
||||
|
||||
let data = item.data;
|
||||
let key = data.CODE;
|
||||
$("#codeList").setCurrentRow(key);
|
||||
};
|
||||
|
||||
codeControl.onCodeSelect = selected => {
|
||||
let codeList = codeControl.codes.dataset;
|
||||
let keys = selected.map(e => codeList.getKey(e));
|
||||
$("#codeList input[type='checkbox']").each(function() {
|
||||
let checkbox = $(this);
|
||||
checkbox.prop("checked", keys.includes(checkbox.val()));
|
||||
});
|
||||
|
||||
$("#btnRemoveCodes").prop("disabled", selected.length < 1);
|
||||
};
|
||||
|
||||
$("#term").onEnterPress(searchGroups);
|
||||
|
||||
$(function(){
|
||||
${onload}
|
||||
codeControl.groups.setData({
|
||||
groupList:${groupList},
|
||||
groupStart:${groupStart},
|
||||
groupFetch:${groupFetch},
|
||||
groupTotal:${groupTotal}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,112 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<form id="group-form">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="id"
|
||||
>아이디</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="id" type="text" required data-map="GRP_ID" maxlength="50" class="form-control" placeholder="그룹 아이디" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="name"
|
||||
>이름</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="name" type="text" required data-map="GRP_NM" maxlength="60" class="form-control" placeholder="그룹 이름" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="description"
|
||||
>설명</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="description" type="text" data-map="DSCRP" maxlength="200" class="form-control" placeholder="그룹 설명"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="createdBy"
|
||||
>등록자</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" data-map="RGTR" readonly class="form-control" placeholder="등록자"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="description"
|
||||
>등록일자</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" data-map="REG_DT" readonly class="form-control" placeholder="등록일자"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="description"
|
||||
>사용여부</label
|
||||
>
|
||||
<div class="col-sm-10" style="padding:.5em .7em;">
|
||||
<span id="groupInUse"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4 justify-content-end">
|
||||
<div class="col-sm-12" style="text-align:right;">
|
||||
<button onclick="saveGroup();" type="button" class="btn btn-primary">저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
|
||||
var groupFields = new FormFields("#group-form");
|
||||
|
||||
codeControl.groups.setInfo = obj => {
|
||||
let info = obj.data;
|
||||
groupFields.set(obj);
|
||||
let create = isEmpty(info.GRP_ID);
|
||||
$("input[name='id']").prop("readonly", !create);
|
||||
$("#group-form input")
|
||||
.change(function() {
|
||||
let input = $(this),
|
||||
name = input.attr("data-map"),
|
||||
val = input.val();
|
||||
codeControl.groups.setValue(name, val);
|
||||
})
|
||||
.onEnterPress(saveGroup);
|
||||
$("#groupInUse").html(create ? "" : info.USE_YN == "Y" ? "사용 중" : "사용하지 않음");
|
||||
|
||||
document.querySelector("input[name='" + (create ? "id" : "name") + "']").focus();
|
||||
}
|
||||
|
||||
codeControl.groups.onModify = (changed) => {
|
||||
if (["GRP_NM"].filter(e => changed.includes(e)).length < 1)
|
||||
return;
|
||||
|
||||
renderGroupList();
|
||||
codeControl.groups.dataset.setState();
|
||||
}
|
||||
|
||||
function saveGroup() {
|
||||
if (!$("#group-form input").validInputs()) return;
|
||||
|
||||
dialog.alert({
|
||||
content:"현재 그룹 정보를 저장하시겠습니까?",
|
||||
onOK:() => {
|
||||
codeControl.groups.save(groupFields.get());
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceURL=group-info.jsp
|
||||
</script>
|
@ -0,0 +1,108 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<form id="menu-form">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="id"
|
||||
>아이디</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="id" type="text" readonly maxlength="50" class="form-control" placeholder="저장하시면 시스템이 부여합니다." />
|
||||
<input name="parentID" type="hidden" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="name"
|
||||
>이름</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="name" type="text" required maxlength="60" class="form-control" placeholder="메뉴 이름" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="action"
|
||||
>URL</label
|
||||
>
|
||||
<div class="col-sm-10 input-group" style="width:83.3%;">
|
||||
<span id="btnSelectURL" onClick="setURL();" class="input-group-text"><i class="bx bx-search"></i></span>
|
||||
<input name="action" type="text" maxlength="60" class="form-control" placeholder="URL" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="description"
|
||||
>설명</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="description" type="text" maxlength="200" class="form-control" placeholder="메뉴 설명"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="imageName"
|
||||
>이미지 이름</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="imageName" type="text" maxlength="200" class="form-control" placeholder="이미지 이름"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 col-form-label text-sm-end" for="imageConf"
|
||||
>이미지 설정</label
|
||||
>
|
||||
<div class="col-sm-10">
|
||||
<input name="imageConf" type="text" maxlength="200" class="form-control" placeholder="이미지 설정"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4 justify-content-end">
|
||||
<div class="col-sm-12" style="text-align:right;">
|
||||
<button id="btnSaveAuth" onclick="saveMenu();" type="button" class="btn btn-primary">저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<c:set var="menuFunc" scope="request">
|
||||
var menuFields = new FormFields("#menu-form");
|
||||
|
||||
menuControl.setInfo = obj => {
|
||||
menuFields.set(obj);
|
||||
$("input[name='name']").focus();
|
||||
}
|
||||
|
||||
menuControl.onModify = (changed) => {
|
||||
if (["name", "url"].filter(e => changed.includes(e)).length < 1)
|
||||
return;
|
||||
}
|
||||
|
||||
async function setURL() {
|
||||
let url = await selectURL(false);
|
||||
$("input[name='action']").val(url).change();
|
||||
}
|
||||
|
||||
function saveMenu() {
|
||||
if (!$("#menu-form input").validInputs()) return;
|
||||
|
||||
dialog.alert({
|
||||
content:"현재 메뉴 정보를 저장하시겠습니까?",
|
||||
onOK:() => menuControl.save(menuFields.get())
|
||||
});
|
||||
}
|
||||
|
||||
$("#menu-form input")
|
||||
.change(function() {
|
||||
let input = $(this),
|
||||
name = input.attr("name"),
|
||||
val = input.val();
|
||||
menuControl.setValue(name, val);
|
||||
})
|
||||
.onEnterPress(() => saveMenu());
|
||||
</c:set>
|
@ -0,0 +1,178 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<jsp:include page="/WEB-INF/jsp/include/head.jsp" />
|
||||
<link rel="stylesheet" href="<c:url value="/resources/3rd-party/sneat/libs/jstree/jstree.css"/>" /--%>
|
||||
<body>
|
||||
<!-- Layout wrapper -->
|
||||
<div class="layout-wrapper layout-content-navbar">
|
||||
<div class="layout-container">
|
||||
<jsp:include page="/WEB-INF/jsp/include/userMenus.jsp" />
|
||||
<!-- Layout container -->
|
||||
<!-- Layout page -->
|
||||
<div class="layout-page">
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/top.jsp" />
|
||||
|
||||
<!-- Content wrapper -->
|
||||
<div class="content-wrapper">
|
||||
<!-- Content -->
|
||||
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<%--h4 id="pageTitle" class="fw-bold py-3 mb-4">페이지 제목</h4--%>
|
||||
<c:set var="prefixName" scope="request">메뉴</c:set>
|
||||
<!-- Page Body -->
|
||||
<div class="card">
|
||||
<div class="card-datatable text-nowrap">
|
||||
<div id="DataTables_Table_0_wrapper" class="dataTables_wrapper dt-bootstrap5 no-footer">
|
||||
|
||||
<div class="d-flex flex-row justify-content-evenly">
|
||||
<div style="width:49%;">
|
||||
<h5 class="mt-3">레이아웃</h5>
|
||||
<div id="menu-tree" class="main-left d-flex flex-column flex-grow-1">
|
||||
<div class="d-flex justify-content-between" style="padding-top:.5em; padding-bottom:.5em; border-top:1px solid #dfdfdf; border-bottom:1px solid #dfdfdf;">
|
||||
<span>
|
||||
<button id="menuToggler" onclick="toggleMenus();" class="btn btn-primary"></button>
|
||||
</span>
|
||||
</div>
|
||||
<div id="menuTree" style="padding-top:1em; min-height:26em; overflow:auto;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width:49%;">
|
||||
<h5 class="mt-3">등록 정보</h5>
|
||||
<div class="d-flex flex-row justify-content-end p-3">
|
||||
<div>
|
||||
<button id="btnRemoveMenus" onclick="removeMenus();" class="btn btn-primary">- 제거</button>
|
||||
</div>
|
||||
</div>
|
||||
<jsp:include page="menu-info.jsp" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Page Body -->
|
||||
|
||||
<hr class="my-5" />
|
||||
</div>
|
||||
<!-- / Content -->
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/bottom.jsp" />
|
||||
|
||||
<div class="content-backdrop fade"></div>
|
||||
</div>
|
||||
<!-- Content wrapper -->
|
||||
</div>
|
||||
<!-- / Layout page -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Layout wrapper -->
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/tail.jsp" />
|
||||
<script src="<c:url value="/resources/3rd-party/sneat/libs/jstree/jstree.js"/>"></script>
|
||||
<script src="<c:url value="/resources/3rd-party/jstree/jstree-support.js"/>"></script>
|
||||
<script src="<c:url value="/resources/js/base/menu.js"/>?${ver}"></script>
|
||||
<script >
|
||||
${functions}
|
||||
${userMenus}
|
||||
var menuBranches = treeSupport({
|
||||
selector:"#menuTree",
|
||||
trace:wctx.trace,
|
||||
plugins: ["checkbox", "contextmenu", "dnd"] ,
|
||||
core:{check_callback:true,
|
||||
multiple:false
|
||||
},
|
||||
checkbox:{
|
||||
whole_node:false,
|
||||
tie_selection:false
|
||||
},
|
||||
contextmenu:{items:{
|
||||
newMenu:{label:"메뉴 추가", action:function(obj){
|
||||
var current = menuControl.getCurrent(),
|
||||
parentID = current.parentID;
|
||||
menuControl.newInfo({parentID:parentID});
|
||||
$("input[name='parentID']").val(parentID);
|
||||
}},
|
||||
newChildMenu:{label:"하위메뉴 추가", action:function(obj){
|
||||
var current = menuControl.getCurrent(),
|
||||
parentID = current.id;
|
||||
menuControl.newInfo({parentID:parentID});
|
||||
$("input[name='parentID']").val(parentID);
|
||||
log("current", menuControl.getCurrent());
|
||||
}},
|
||||
}},
|
||||
onNodeSelect:function(obj) {
|
||||
var key = obj[0];
|
||||
menuControl.setCurrent(key);
|
||||
},
|
||||
onNodeMove:function(obj) {
|
||||
var parentID = obj.parent,
|
||||
menuID = obj.node.id;
|
||||
if (parentID == "#")
|
||||
parentID = null;
|
||||
menuControl.move(parentID, menuID);
|
||||
},
|
||||
onNodeReorder:function(obj) {
|
||||
var parentID = obj.parent,
|
||||
menuID = obj.node.id,
|
||||
menuIDs = menuBranches.getChildIDs(parentID);
|
||||
menuControl.reorder(menuIDs);
|
||||
},
|
||||
onNodeCheck:function(obj) {
|
||||
var checked = obj.checked,
|
||||
menuID = obj.node.id;
|
||||
menuControl.select(menuID, checked);
|
||||
}
|
||||
});
|
||||
|
||||
function toggleMenus() {
|
||||
$("#menuToggler").text(menuBranches.toggleFolding() == "collapsed" ? "+ 펼치기" : "- 닫기");
|
||||
}
|
||||
|
||||
let menuControl = new MenuControl();
|
||||
|
||||
menuControl.onDatasetChange = obj => {
|
||||
menuBranches.setData(treeHtml(menuControl.menus, {
|
||||
id:function(e){return e.id;},
|
||||
text:function(e){
|
||||
return e.name == e.url ? e.name : e.name + (e.url ? " (" + e.url + ")" : "");
|
||||
}
|
||||
}));
|
||||
$("#btnSelectURL").prop("disabled", menuControl.dataset.empty);
|
||||
}
|
||||
|
||||
menuControl.onCurrentChange = item => {
|
||||
menuControl.setInfo(item.data);
|
||||
menuBranches.selectNode(item.data.id);
|
||||
}
|
||||
|
||||
menuControl.onSelectionChange = selected => {
|
||||
$("#btnRemoveMenus").prop("disabled", selected.length < 1);
|
||||
}
|
||||
|
||||
menuControl.onMenusChanged = () => loadUserMenus();
|
||||
|
||||
${menuFunc}
|
||||
|
||||
async function loadUserMenus() {
|
||||
let userMenus = await menuControl.getUserMenus();
|
||||
setUserMenus(userMenus);
|
||||
}
|
||||
|
||||
function removeMenus() {
|
||||
dialog.alert({
|
||||
content:"선택한 메뉴 정보를 삭제하시겠습니까?",
|
||||
onOK:() => menuControl.remove()
|
||||
});
|
||||
}
|
||||
|
||||
$(function(){
|
||||
${onload}
|
||||
$("#menuToggler").text(menuBranches._folding == "collapsed" ? "+ 펼치기" : "- 닫기");
|
||||
menuControl.setData(${menus});
|
||||
menuBranches.open();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,122 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<c:set var="prefixName" scope="request">사용자</c:set>
|
||||
<!-- Page Body -->
|
||||
<div class="card">
|
||||
<div class="card-datatable text-nowrap">
|
||||
<div id="DataTables_Table_0_wrapper" class="dataTables_wrapper dt-bootstrap5 no-footer">
|
||||
<div class="d-flex flex-row justify-content-between p-3">
|
||||
<div>
|
||||
<div class="input-group" id="DataTables_Table_0_length">
|
||||
<select id="_userBy" onchange="document.getElementById('_userTerm').focus();" aria-controls="DataTables_Table_0" class="form-select">
|
||||
<option value="${infoPrefix}Name">이름</option>
|
||||
<option value="${infoPrefix}ID">아이디</option>
|
||||
</select>
|
||||
<input id="_userTerm" autofocus type="text" placeholder="조회 조건을 입력하십시오." class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="search${infoPrefix}s();" class="btn btn-primary">찾기</button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="datatables-ajax table table-bordered dataTable no-footer" id="DataTables_Table_0" aria-describedby="DataTables_Table_0_info">
|
||||
<thead>
|
||||
<tr><th tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" style="text-align:center;"><input onchange="${infoPrefix}Control.dataset.select(this.checked);" type="checkbox" class="form-check-input"></th>
|
||||
<th class="sorting sorting_asc" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Full name: activate to sort column descending" style="">아이디</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Email: activate to sort column ascending" style="">이름</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Start date: activate to sort column ascending" style="">등록일자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="_${infoPrefix}List">
|
||||
</tbody>
|
||||
<template id="_${infoPrefix}Row">
|
||||
<tr data-key="{USER_ID}">
|
||||
<td style="text-align:center;"><input value="{USER_ID}" onchange="${infoPrefix}Control.dataset.select('{USER_ID}', this.checked);" type="checkbox" class="form-check-input"></td>
|
||||
<td onclick="${infoPrefix}Control.setCurrent('{USER_ID}')" ondblclick="${infoPrefix}Control.getInfo({})">{USER_ID}</td>
|
||||
<td onclick="${infoPrefix}Control.setCurrent('{USER_ID}')" ondblclick="${infoPrefix}Control.getInfo({})">{USER_NM}</td>
|
||||
<td onclick="${infoPrefix}Control.setCurrent('{USER_ID}')" ondblclick="${infoPrefix}Control.getInfo({})">{REG_DT}</td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="_${infoPrefix}NotFound">
|
||||
<tr class="odd">
|
||||
<td valign="top" colspan="4" class="dataTables_empty text-center">${prefixName} 정보를 찾지 못했습니다.</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
<div class="d-flex flex-row p-3 justify-content-between">
|
||||
<label id="_${infoPrefix}PagingInfo" class="dataTables_info" role="status" aria-live="polite"></label>
|
||||
<ul id="_${infoPrefix}Paging" class="pagination pagination-primary">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Page Body -->
|
||||
<script >
|
||||
var ${infoPrefix}Control = new UserControl();
|
||||
|
||||
function getSelectedUser() {
|
||||
let selected = ${infoPrefix}Control.dataset.getKeys("selected");
|
||||
if (selected.length < 1)
|
||||
return dialog.alert("사용자를 선택하십시오.");
|
||||
else
|
||||
return selected;
|
||||
}
|
||||
|
||||
function search${infoPrefix}s() {
|
||||
${infoPrefix}Control.query = {
|
||||
by:$("#_userBy").val(),
|
||||
term:$("#_userTerm").val()
|
||||
};
|
||||
${infoPrefix}Control.load(1);
|
||||
}
|
||||
|
||||
${infoPrefix}Control.onDatasetChange = obj => {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.dataset;
|
||||
let empty = ${infoPrefix}List.empty;
|
||||
|
||||
let trs = empty ?
|
||||
[document.getElementById("_${infoPrefix}NotFound").innerHTML] : <%-- from template#${infoPrefix}NotFound --%>
|
||||
${infoPrefix}List.inStrings(document.getElementById("_${infoPrefix}Row").innerHTML); <%-- from template#${infoPrefix}Row --%>
|
||||
$("#_${infoPrefix}List").html(trs.join());
|
||||
$("th input[type='checkbox']").prop("checked", false);
|
||||
|
||||
$("#_${infoPrefix}Paging").setPaging({
|
||||
list:${infoPrefix}Control.dataset,
|
||||
prefix:${infoPrefix}Control.prefix,
|
||||
start:obj.${infoPrefix}Start,
|
||||
totalSize:obj.${infoPrefix}Total,
|
||||
fetchSize:obj.${infoPrefix}Fetch,
|
||||
func:"${infoPrefix}Control.load({index})"
|
||||
});
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onCurrentChange = item => {
|
||||
if (!item) return;
|
||||
|
||||
let key = item.data.USER_ID;
|
||||
$("#_${infoPrefix}List").setCurrentRow(key);
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onSelectionChange = selected => {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.dataset;
|
||||
let keys = selected.map(e => ${infoPrefix}List.getKey(e));
|
||||
$("#_${infoPrefix}List input[type='checkbox']").each(function() {
|
||||
let checkbox = $(this);
|
||||
checkbox.prop("checked", keys.includes(checkbox.val()));
|
||||
});
|
||||
};
|
||||
|
||||
$("#_userTerm").onEnterPress(search${infoPrefix}s);
|
||||
|
||||
$(function(){
|
||||
${onload}
|
||||
${infoPrefix}Control.setData({
|
||||
${infoPrefix}List:${userList},
|
||||
${infoPrefix}Start:${userStart},
|
||||
${infoPrefix}Fetch:${userFetch},
|
||||
${infoPrefix}Total:${userTotal}
|
||||
});
|
||||
});
|
||||
//# sourceURL=select-user.jsp
|
||||
</script>
|
@ -0,0 +1,200 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<form id="infoPrefix-form">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<div class="row">
|
||||
<label class="col-sm-3 col-form-label text-sm-end" for="account"
|
||||
>계정</label
|
||||
>
|
||||
<div class="col-sm-9">
|
||||
<input name="id" type="hidden" data-map="USER_ID" />
|
||||
<input name="institute" type="hidden" data-map="NSTT_CD" />
|
||||
<input name="account" type="text" required data-map="USER_ACNT" class="form-control" placeholder="prefixName 계정" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="row">
|
||||
<label class="col-sm-3 col-form-label text-sm-end" for="name"
|
||||
>이름</label
|
||||
>
|
||||
<div class="col-sm-9">
|
||||
<input name="name" type="text" required data-map="USER_NM" class="form-control" placeholder="prefixName 이름" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="row">
|
||||
<label class="col-sm-3 col-form-label text-sm-end" for="password"
|
||||
>비밀번호</label
|
||||
>
|
||||
<div class="col-sm-9">
|
||||
<input name="password" type="password" required class="form-control" placeholder="비밀번호" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 hidden">
|
||||
<div class="row">
|
||||
<label class="col-sm-3 col-form-label text-sm-end" for="confirmPassword"
|
||||
>비밀번호 확인</label
|
||||
>
|
||||
<div class="col-sm-9">
|
||||
<input name="confirmPassword" type="password" required class="form-control" placeholder="비밀번호 확인" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="row">
|
||||
<label class="col-sm-3 col-form-label text-sm-end" for="birthday"
|
||||
>생년월일</label
|
||||
>
|
||||
<div class="col-sm-9">
|
||||
<input name="birthday" type="text" data-map="BRDT" class="form-control dob-picker" placeholder="YYYY-MM-DD"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="row">
|
||||
<label class="col-sm-3 col-form-label text-sm-end" for="gender"
|
||||
>성별</label
|
||||
>
|
||||
<div class="col-sm-9">
|
||||
<div class="form-check form-check-inline mt-3">
|
||||
<input name="gender" value="M" type="radio" data-map="GENDER" class="form-check-input"/>
|
||||
<label class="form-check-label" for="male">남자</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input name="gender" value="F" type="radio" data-map="GENDER" class="form-check-input"/>
|
||||
<label class="form-check-label" for="female">여자</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="row">
|
||||
<label class="col-sm-3 col-form-label text-sm-end" for="emailAddress"
|
||||
>이메일 주소</label
|
||||
>
|
||||
<div class="col-sm-9">
|
||||
<input name="emailAddress" type="email" required data-map="EML_ADRS" class="form-control" placeholder="이메일 주소" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 select2-primary">
|
||||
<div class="row">
|
||||
<label class="col-sm-3 col-form-label text-sm-end" for="mobilePhoneNo"
|
||||
>전화번호(무선)</label
|
||||
>
|
||||
<div class="col-sm-9">
|
||||
<input name="mobilePhoneNo" type="text" data-map="MBL_TELNO" class="form-control phone-mask" placeholder="010-0000-0000" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 select2-primary">
|
||||
<div class="row">
|
||||
<label class="col-sm-3 col-form-label text-sm-end" for="phoneNo"
|
||||
>전화번호(유선)</label
|
||||
>
|
||||
<div class="col-sm-9">
|
||||
<input name="phoneNo" type="text" data-map="TELNO" class="form-control phone-mask" placeholder="000-0000-0000" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="row">
|
||||
<label class="col-sm-3 col-form-label text-sm-end" for="faxNo">팩스</label>
|
||||
<div class="col-sm-9">
|
||||
<input name="faxNo" type="text" data-map="FXNO" class="form-control phone-mask" placeholder="000-0000-0000"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="row">
|
||||
<label class="col-sm-3 col-form-label text-sm-end" for=positionName>직위</label>
|
||||
<div class="col-sm-9">
|
||||
<input name="positionName" type="text" data-map="POS_NM" class="form-control" placeholder="직위"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="row">
|
||||
<label class="col-sm-3 col-form-label text-sm-end" for="status">상태</label>
|
||||
<div class="col-sm-9">
|
||||
<input name="status" type="text" data-map="STTS" class="form-control" placeholder="상태"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4 justify-content-end">
|
||||
<div class="col-md-6">
|
||||
<div class="row justify-content-end">
|
||||
<div class="col-sm-3">
|
||||
<button onclick="saveinfoPrefix();" type="button" class="btn btn-primary">저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
|
||||
var infoPrefixFields = new FormFields("#infoPrefix-form");
|
||||
|
||||
infoPrefixControl.setInfo = obj => {
|
||||
infoPrefixFields.set(obj);
|
||||
let create = isEmpty(obj.data.USER_ACNT);
|
||||
$("input[name='account']").prop("readonly", !create);
|
||||
$("input[type='password']").each(function(){
|
||||
let password = $(this).prop("required", create);
|
||||
let div = password.parent().parent().parent();
|
||||
if (create) {
|
||||
$("input[name='institute']").val("default");
|
||||
div.show();
|
||||
} else
|
||||
div.hide();
|
||||
});
|
||||
$("#infoPrefix-form input")
|
||||
.change(function() {
|
||||
let input = $(this),
|
||||
name = input.attr("data-map"),
|
||||
val = input.val();
|
||||
infoPrefixControl.setValue(name, val);
|
||||
})
|
||||
.onEnterPress(saveinfoPrefix);
|
||||
|
||||
document.querySelector("input[name='" + (create ? "account" : "name") + "']").focus();
|
||||
}
|
||||
|
||||
infoPrefixControl.onModify = (changed) => {
|
||||
if (["USER_NM", "EML_ADRS", "MBL_TELNO"].filter(e => changed.includes(e)).length < 1)
|
||||
return;
|
||||
|
||||
renderinfoPrefixList();
|
||||
infoPrefixControl.dataset.setState();
|
||||
}
|
||||
|
||||
function saveinfoPrefix() {
|
||||
if (!$("#infoPrefix-form input").validInputs()) return;
|
||||
|
||||
let match = Array.from(document.querySelectorAll("input[type='password']"))
|
||||
.map(input => input.value)
|
||||
.reduce((total, current) => total == current);
|
||||
if (!match) {
|
||||
dialog.alert({
|
||||
content:"비밀번호와 비밀번호 확인이 다릅니다.",
|
||||
onClose:function(){
|
||||
document.querySelector("input[name='confirmPassword']").focus();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
dialog.alert({
|
||||
content:"현재 prefixName 정보를 저장하시겠습니까?",
|
||||
onOK:() => {
|
||||
infoPrefixControl.save(infoPrefixFields.get());
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceURL=user-info.jsp
|
||||
</script>
|
@ -0,0 +1,179 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<jsp:include page="/WEB-INF/jsp/include/head.jsp" />
|
||||
<body>
|
||||
<!-- Layout wrapper -->
|
||||
<div class="layout-wrapper layout-content-navbar">
|
||||
<div class="layout-container">
|
||||
<jsp:include page="/WEB-INF/jsp/include/userMenus.jsp" />
|
||||
<!-- Layout container -->
|
||||
<!-- Layout page -->
|
||||
<div class="layout-page">
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/top.jsp" />
|
||||
|
||||
<!-- Content wrapper -->
|
||||
<div class="content-wrapper">
|
||||
<!-- Content -->
|
||||
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<%--h4 id="pageTitle" class="fw-bold py-3 mb-4">페이지 제목</h4--%>
|
||||
<c:set var="prefixName" scope="request">사용자</c:set>
|
||||
<!-- Page Body -->
|
||||
<div class="card">
|
||||
<div class="card-datatable text-nowrap">
|
||||
<div id="DataTables_Table_0_wrapper" class="dataTables_wrapper dt-bootstrap5 no-footer">
|
||||
|
||||
<div class="d-flex flex-row justify-content-between p-3">
|
||||
<div>
|
||||
<div class="input-group" id="DataTables_Table_0_length">
|
||||
<select id="by" onchange="document.getElementById('term').focus();" aria-controls="DataTables_Table_0" class="form-select">
|
||||
<option value="${infoPrefix}Name">이름</option>
|
||||
<option value="${infoPrefix}Account">계정</option>
|
||||
</select>
|
||||
<input id="term" autofocus type="text" placeholder="조회 조건을 입력하십시오." class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="search${infoPrefix}s();" class="btn btn-primary">찾기</button>
|
||||
<button onclick="${infoPrefix}Control.newInfo();" class="btn btn-primary">+ 추가</button>
|
||||
<button id="btnRemove${infoPrefix}s" onclick="remove${infoPrefix}s();" class="btn btn-primary">- 제거</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="datatables-ajax table table-bordered dataTable no-footer" id="DataTables_Table_0" aria-describedby="DataTables_Table_0_info">
|
||||
<thead>
|
||||
<tr><th tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" style="width: 158.828px; text-align:center;"><input onchange="${infoPrefix}Control.select(this.checked);" type="checkbox" class="form-check-input"></th>
|
||||
<th class="sorting sorting_asc" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Full name: activate to sort column descending" style="width: 223.719px;">계정</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Email: activate to sort column ascending" style="width: 146.156px;">이름</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Position: activate to sort column ascending" style="width: 195.688px;">이메일</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Office: activate to sort column ascending" style="width: 160.141px;">전화번호(무선)</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Start date: activate to sort column ascending" style="width: 230.469px;">등록일자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="${infoPrefix}List">
|
||||
</tbody>
|
||||
<template id="${infoPrefix}Row">
|
||||
<tr data-key="{USER_ID}">
|
||||
<td style="text-align:center;"><input value="{USER_ID}" onchange="${infoPrefix}Control.select('{USER_ID}', this.checked);" type="checkbox" class="form-check-input"></td>
|
||||
<td onclick="${infoPrefix}Control.setCurrent('{USER_ID}')" ondblclick="${infoPrefix}Control.getInfo({})">{USER_ACNT}</td>
|
||||
<td onclick="${infoPrefix}Control.setCurrent('{USER_ID}')" ondblclick="${infoPrefix}Control.getInfo({})">{USER_NM}</td>
|
||||
<td onclick="${infoPrefix}Control.setCurrent('{USER_ID}')" ondblclick="${infoPrefix}Control.getInfo({})">{EML_ADRS}</td>
|
||||
<td onclick="${infoPrefix}Control.setCurrent('{USER_ID}')" ondblclick="${infoPrefix}Control.getInfo({})">{MBL_TELNO}</td>
|
||||
<td onclick="${infoPrefix}Control.setCurrent('{USER_ID}')" ondblclick="${infoPrefix}Control.getInfo({})">{REG_DT}</td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="${infoPrefix}NotFound">
|
||||
<tr class="odd">
|
||||
<td valign="top" colspan="6" class="dataTables_empty text-center">${prefixName} 정보를 찾지 못했습니다.</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
</div>
|
||||
<div class="d-flex flex-row p-3 justify-content-between">
|
||||
<label id="${infoPrefix}PagingInfo" class="dataTables_info" role="status" aria-live="polite"></label>
|
||||
<ul id="${infoPrefix}Paging" class="pagination pagination-primary">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Page Body -->
|
||||
|
||||
<hr class="my-5" />
|
||||
</div>
|
||||
<!-- / Content -->
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/bottom.jsp" />
|
||||
|
||||
<div class="content-backdrop fade"></div>
|
||||
</div>
|
||||
<!-- Content wrapper -->
|
||||
</div>
|
||||
<!-- / Layout page -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Layout wrapper -->
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/tail.jsp" />
|
||||
<script src="<c:url value="/resources/js/base/user.js?${ver}"/>"></script>
|
||||
<script >
|
||||
${functions}
|
||||
${userMenus}
|
||||
|
||||
let ${infoPrefix}Control = new UserControl();
|
||||
|
||||
function search${infoPrefix}s() {
|
||||
${infoPrefix}Control.query = {
|
||||
by:$("#by").val(),
|
||||
term:$("#term").val()
|
||||
};
|
||||
${infoPrefix}Control.load(1);
|
||||
}
|
||||
|
||||
function remove${infoPrefix}s() {
|
||||
dialog.alert({
|
||||
content:"선택한 ${prefixName} 정보를 제거하시겠습니까?",
|
||||
onOK:() => {
|
||||
${infoPrefix}Control.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function render${infoPrefix}List() {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.dataset;
|
||||
let empty = ${infoPrefix}List.empty;
|
||||
|
||||
let trs = empty ?
|
||||
[document.getElementById("${infoPrefix}NotFound").innerHTML] : <%-- from template#${infoPrefix}NotFound --%>
|
||||
${infoPrefix}List.inStrings(document.getElementById("${infoPrefix}Row").innerHTML); <%-- from template#${infoPrefix}Row --%>
|
||||
$("#${infoPrefix}List").html(trs.join());
|
||||
$("th input[type='checkbox']").prop("checked", false);
|
||||
}
|
||||
|
||||
${infoPrefix}Control.onDatasetChange = obj => {
|
||||
render${infoPrefix}List();
|
||||
|
||||
$("#${infoPrefix}Paging").setPaging({
|
||||
list:${infoPrefix}Control.dataset,
|
||||
prefix:${infoPrefix}Control.prefix,
|
||||
start:obj.${infoPrefix}Start,
|
||||
totalSize:obj.${infoPrefix}Total,
|
||||
fetchSize:obj.${infoPrefix}Fetch,
|
||||
func:"${infoPrefix}Control.load({index})"
|
||||
});
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onCurrentChange = item => {
|
||||
if (!item) return;
|
||||
|
||||
let key = item.data.USER_ID;
|
||||
$("#${infoPrefix}List").setCurrentRow(key);
|
||||
};
|
||||
|
||||
${infoPrefix}Control.onSelectionChange = selected => {
|
||||
let ${infoPrefix}List = ${infoPrefix}Control.dataset;
|
||||
let keys = selected.map(e => ${infoPrefix}List.getKey(e));
|
||||
$("#${infoPrefix}List input[type='checkbox']").each(function() {
|
||||
let checkbox = $(this);
|
||||
checkbox.prop("checked", keys.includes(checkbox.val()));
|
||||
});
|
||||
|
||||
$("#btnRemove${infoPrefix}s").prop("disabled", keys.length < 1);
|
||||
};
|
||||
|
||||
$("#term").onEnterPress(search${infoPrefix}s);
|
||||
|
||||
$(function(){
|
||||
${onload}
|
||||
${infoPrefix}Control.setData({
|
||||
${infoPrefix}List:${userList},
|
||||
${infoPrefix}Start:${userStart},
|
||||
${infoPrefix}Fetch:${userFetch},
|
||||
${infoPrefix}Total:${userTotal}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,80 @@
|
||||
<%@ page language="java" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<%@ page import="java.util.HashMap, javax.servlet.http.HttpServletRequest, cokr.xit.foundation.data.Convert" %>
|
||||
<%! private static final HashMap<String, String> titles = new HashMap<>();
|
||||
|
||||
static {
|
||||
titles.put("404", "Page Not Found");
|
||||
titles.put("sessionExpired", "Session Expired");
|
||||
titles.put("invalidSession", "Invalid Session");
|
||||
titles.put("accessDenied", "Access Denied");
|
||||
titles.put("500", "Server Error");
|
||||
}
|
||||
|
||||
private static void setTitle(HttpServletRequest hreq) {
|
||||
String status = Convert.toString(hreq.getAttribute("status"));
|
||||
if (status == "")
|
||||
status = "500";
|
||||
String title = titles.get(status);
|
||||
if (title == null)
|
||||
title = titles.get("500");
|
||||
hreq.setAttribute("title", title);
|
||||
}
|
||||
%>
|
||||
<% setTitle(request); %>
|
||||
<c:if test="${json}"><%
|
||||
response.setContentType("application/json; charset=UTF-8");
|
||||
%>{
|
||||
"path": "${path}",
|
||||
"failed": true,
|
||||
"status": "${status}",
|
||||
"title": "${title}",
|
||||
"message": "${message}",
|
||||
"description": "${description}",
|
||||
"stacktrace": "${stacktrace}"
|
||||
}</c:if>
|
||||
<c:if test="${!json}"><%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<jsp:include page="/WEB-INF/jsp/include/head.jsp" />
|
||||
<style>
|
||||
.misc-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: calc(100vh - (1.625rem * 2));
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<!-- Content -->
|
||||
|
||||
<!-- Error -->
|
||||
<div class="container-xxl container-p-y">
|
||||
<div class="misc-wrapper">
|
||||
<h2 class="mb-2 mx-2">${title} :(</h2>
|
||||
<p class="mb-4 mx-2">죄송합니다. 😖</p>
|
||||
<p class="mb-4 mx-2">${message}</p>
|
||||
<a onclick="wctx.home();" class="btn btn-primary" href="javascript:void(0);">처음으로 돌아가기</a>
|
||||
<a onclick="history.back();" class="btn btn-primary mt-2" href="javascript:void(0);" autofocus>이전으로 돌아가기</a>
|
||||
<div class="mt-3">
|
||||
<img
|
||||
src="<c:url value="/resources/img/illustrations/page-misc-error-light.png"/>"
|
||||
alt="page-misc-error-light"
|
||||
width="500"
|
||||
class="img-fluid"
|
||||
data-app-dark-img="illustrations/page-misc-error-dark.png"
|
||||
data-app-light-img="illustrations/page-misc-error-light.png"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Error -->
|
||||
|
||||
<!-- / Content -->
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/tail.jsp" />
|
||||
<script>
|
||||
${functions}
|
||||
</script>
|
||||
</body>
|
||||
</html></c:if>
|
@ -0,0 +1,34 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<!-- Footer -->
|
||||
<footer class="content-footer footer bg-footer-theme">
|
||||
<div class="container-xxl d-flex flex-wrap justify-content-between py-2 flex-md-row flex-column">
|
||||
<div class="mb-2 mb-md-0">
|
||||
©
|
||||
<script>
|
||||
document.write(new Date().getFullYear());
|
||||
</script>
|
||||
, made with XIT Base by
|
||||
<a href="http://xit.co.kr" target="_blank" class="footer-link fw-bolder">(주)엑스아이티</a>
|
||||
</div>
|
||||
<%--div>
|
||||
<a href="https://themeselection.com/license/" class="footer-link me-4" target="_blank">License</a>
|
||||
<a href="https://themeselection.com/" target="_blank" class="footer-link me-4">More Themes</a>
|
||||
|
||||
<a
|
||||
href="https://demos.themeselection.com/sneat-bootstrap-html-admin-template/documentation/"
|
||||
target="_blank"
|
||||
class="footer-link me-4"
|
||||
>Documentation</a
|
||||
>
|
||||
|
||||
<a
|
||||
href="https://themeselection.com/support/"
|
||||
target="_blank"
|
||||
class="footer-link d-none d-sm-inline-block"
|
||||
>Support</a
|
||||
>
|
||||
</div--%>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- / Footer -->
|
@ -0,0 +1,41 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<!DOCTYPE html>
|
||||
<html
|
||||
lang="kr"
|
||||
class="light-style layout-navbar-fixed layout-menu-fixed "
|
||||
dir="ltr"
|
||||
data-theme="theme-default"
|
||||
data-assets-path="<c:url value="/resources/"/>"
|
||||
data-template="vertical-menu-template-starter">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>XIT Base Example</title>
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/x-icon" href="<c:url value="/resources/image/favicon.ico"/>" />
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Icons. Uncomment required icon fonts -->
|
||||
<link rel="stylesheet" href="<c:url value="/resources/3rd-party/sneat/fonts/boxicons.css"/>" />
|
||||
<link rel="stylesheet" href="<c:url value="/resources/3rd-party/sneat/fonts/fontawesome.css"/>" />
|
||||
<link rel="stylesheet" href="<c:url value="/resources/3rd-party/sneat/fonts/flag-icons.css"/>" />
|
||||
<!-- Core CSS -->
|
||||
<link rel="stylesheet" href="<c:url value="/resources/3rd-party/sneat/css/rtl/core.css"/>" class="template-customizer-core-css" />
|
||||
<link rel="stylesheet" href="<c:url value="/resources/3rd-party/sneat/css/rtl/theme-default.css"/>" class="template-customizer-theme-css" />
|
||||
<%--link rel="stylesheet" href="<c:url value="/resources/3rd-party/sneat/css/demo.css" /--%>
|
||||
<!-- Vendors CSS -->
|
||||
<link rel="stylesheet" href="<c:url value="/resources/3rd-party/sneat/libs/perfect-scrollbar/perfect-scrollbar.css"/>" />
|
||||
<%--link rel="stylesheet" href="<c:url value="/resources/3rd-party/sneat/libs/typeahead-js/typeahead.css"/>" />
|
||||
<link rel="stylesheet" href="<c:url value="/resources/3rd-party/sneat/libs/datatables-bs5/datatables.bootstrap5.css"/>" />
|
||||
<link rel="stylesheet" href="<c:url value="/resources/3rd-party/sneat/libs/datatables-responsive-bs5/responsive.bootstrap5.css"/>" />
|
||||
<link rel="stylesheet" href="<c:url value="/resources/3rd-party/sneat/libs/flatpickr/flatpickr.css"/>" /--%>
|
||||
|
||||
<link rel="stylesheet" href="<c:url value="/resources/css/styles.css"/>" />
|
||||
|
||||
</head>
|
@ -1,11 +1,4 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
|
||||
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
|
||||
<%--@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"--%>
|
||||
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
|
||||
<%--@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"--%>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
|
||||
<%--@ taglib prefix="validator" uri="http://www.springmodules.org/tags/commons-validator" --%>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"
|
||||
%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"
|
||||
%><%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"
|
||||
%><%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
|
@ -0,0 +1,72 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<div class="spinner-border spinner-border-lg text-primary wait" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
<!-- Helpers -->
|
||||
<script src="<c:url value="/resources/3rd-party/sneat/js/helpers.js"/>"></script>
|
||||
|
||||
<!--! Template customizer & Theme config files MUST be included after core stylesheets and helpers.js in the <head> section -->
|
||||
<!--? Template customizer: To hide customizer set displayCustomizer value false in config.js. -->
|
||||
<script src="<c:url value="/resources/3rd-party/sneat/js/template-customizer.js"/>"></script>
|
||||
<%--? Config: Mandatory theme config file contain global vars & default theme options, Set your preferred theme option in this file. -->
|
||||
<script src="../../assets/js/config.js"></script--%>
|
||||
|
||||
<!-- Core JS -->
|
||||
<!-- build:js assets/vendor/js/core.js -->
|
||||
<script src="<c:url value="/resources/3rd-party/sneat/libs/jquery/jquery.js"/>"></script>
|
||||
<script src="<c:url value="/resources/3rd-party/jquery-ui/1.13.2/jquery-ui.js"/>"></script>
|
||||
<script src="<c:url value="/resources/3rd-party/sneat/libs/popper/popper.js"/>"></script>
|
||||
<script src="<c:url value="/resources/3rd-party/sneat/js/bootstrap.js"/>"></script>
|
||||
<script src="<c:url value="/resources/3rd-party/sneat/libs/perfect-scrollbar/perfect-scrollbar.js"/>"></script>
|
||||
<script src="<c:url value="/resources/3rd-party/sneat/libs/hammer/hammer.js"/>"></script>
|
||||
<script src="<c:url value="/resources/3rd-party/sneat/libs/i18n/i18n.js"/>"></script>
|
||||
<script src="<c:url value="/resources/3rd-party/sneat/js/menu.js"/>"></script>
|
||||
<script src="<c:url value="/resources/js/base/base.js?${ver}"/>"></script>
|
||||
<script src="<c:url value="/resources/js/base/dataset.js?${ver}"/>"></script>
|
||||
<script src="<c:url value="/resources/js/base/menu-support.js?${ver}"/>"></script>
|
||||
<!-- endbuild -->
|
||||
<c:set var="functions" scope="request">
|
||||
wctx.path = "${pageContext.request.contextPath}";
|
||||
wctx.version = "${ver}";
|
||||
wctx.trace = ${!production};
|
||||
wctx.csrf = {
|
||||
header:"${_csrf.headerName}",
|
||||
token:"${_csrf.token}"
|
||||
};
|
||||
dialog.title = "XIT Base";
|
||||
|
||||
<c:if test="${currentUser.authenticated}">
|
||||
function logout() {
|
||||
dialog.alert({
|
||||
content:"로그아웃 하시겠습니까?",
|
||||
onOK:function(){
|
||||
var form = $("<form action=\"<c:url value='/logout.do'/>\", method=\"POST\">");
|
||||
$("<input name=\"${_csrf.parameterName}\" value=\"${_csrf.token}\" type=\"hidden\">").appendTo(form);
|
||||
form.appendTo("body").submit();
|
||||
}
|
||||
});
|
||||
}</c:if>
|
||||
|
||||
<c:if test="${currentUser.hasAuthorities('ROLE_ADMIN')}">
|
||||
async function selectURL(multiple) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
ajax.get({
|
||||
url:wctx.url("/urls.do"),
|
||||
data:{multiple:multiple},
|
||||
success: resp => {
|
||||
dialog.open({
|
||||
title:"URL 선택",
|
||||
content:resp,
|
||||
getData:() => getSelectedURL(),
|
||||
onOK:selected => {
|
||||
resolve(selected);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
</c:if>
|
||||
|
||||
${functions}</c:set>
|
@ -0,0 +1,484 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
</-- Navbar -->
|
||||
|
||||
<nav
|
||||
class="layout-navbar container-xxl navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme"
|
||||
id="layout-navbar"
|
||||
>
|
||||
<div class="layout-menu-toggle navbar-nav align-items-xl-center me-3 me-xl-0 d-xl-none">
|
||||
<a class="nav-item nav-link px-0 me-xl-4" href="javascript:void(0)">
|
||||
<i class="bx bx-menu bx-sm"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="navbar-nav-right d-flex align-items-center" id="navbar-collapse">
|
||||
<!-- Search -->
|
||||
<div class="navbar-nav align-items-center">
|
||||
<div class="nav-item navbar-search-wrapper mb-0">
|
||||
<a class="nav-item nav-link search-toggler px-0" href="javascript:void(0);">
|
||||
<span id="pageTitle" class="fw-bold" style="font-size:x-large;"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Search -->
|
||||
|
||||
<ul class="navbar-nav flex-row align-items-center ms-auto">
|
||||
<%-- Language -->
|
||||
<li class="nav-item dropdown-language dropdown me-2 me-xl-0">
|
||||
<a class="nav-link dropdown-toggle hide-arrow" href="javascript:void(0);" data-bs-toggle="dropdown">
|
||||
<i class="fi fi-us fis rounded-circle fs-3 me-1"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="en">
|
||||
<i class="fi fi-us fis rounded-circle fs-4 me-1"></i>
|
||||
<span class="align-middle">English</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="fr">
|
||||
<i class="fi fi-fr fis rounded-circle fs-4 me-1"></i>
|
||||
<span class="align-middle">France</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="de">
|
||||
<i class="fi fi-de fis rounded-circle fs-4 me-1"></i>
|
||||
<span class="align-middle">German</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="pt">
|
||||
<i class="fi fi-pt fis rounded-circle fs-4 me-1"></i>
|
||||
<span class="align-middle">Portuguese</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!--/ Language --%>
|
||||
|
||||
<!-- Style Switcher -->
|
||||
<li class="nav-item me-2 me-xl-0">
|
||||
<a class="nav-link style-switcher-toggle hide-arrow" href="javascript:void(0);">
|
||||
<i class="bx bx-sm"></i>
|
||||
</a>
|
||||
</li>
|
||||
<!--/ Style Switcher -->
|
||||
|
||||
<%-- Quick links -->
|
||||
<li class="nav-item dropdown-shortcuts navbar-dropdown dropdown me-2 me-xl-0">
|
||||
<a
|
||||
class="nav-link dropdown-toggle hide-arrow"
|
||||
href="javascript:void(0);"
|
||||
data-bs-toggle="dropdown"
|
||||
data-bs-auto-close="outside"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<i class="bx bx-grid-alt bx-sm"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-end py-0">
|
||||
<div class="dropdown-menu-header border-bottom">
|
||||
<div class="dropdown-header d-flex align-items-center py-3">
|
||||
<h5 class="text-body mb-0 me-auto">Shortcuts</h5>
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
class="dropdown-shortcuts-add text-body"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="Add shortcuts"
|
||||
><i class="bx bx-sm bx-plus-circle"></i
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-shortcuts-list scrollable-container">
|
||||
<div class="row row-bordered overflow-visible g-0">
|
||||
<div class="dropdown-shortcuts-item col">
|
||||
<span class="dropdown-shortcuts-icon bg-label-secondary rounded-circle mb-2">
|
||||
<i class="bx bx-calendar fs-4"></i>
|
||||
</span>
|
||||
<a href="app-calendar.html" class="stretched-link">Calendar</a>
|
||||
<small class="text-muted mb-0">Appointments</small>
|
||||
</div>
|
||||
<div class="dropdown-shortcuts-item col">
|
||||
<span class="dropdown-shortcuts-icon bg-label-secondary rounded-circle mb-2">
|
||||
<i class="bx bx-food-menu fs-4"></i>
|
||||
</span>
|
||||
<a href="app-invoice-list.html" class="stretched-link">Invoice App</a>
|
||||
<small class="text-muted mb-0">Manage Accounts</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row row-bordered overflow-visible g-0">
|
||||
<div class="dropdown-shortcuts-item col">
|
||||
<span class="dropdown-shortcuts-icon bg-label-secondary rounded-circle mb-2">
|
||||
<i class="bx bx-user fs-4"></i>
|
||||
</span>
|
||||
<a href="app-user-list.html" class="stretched-link">User App</a>
|
||||
<small class="text-muted mb-0">Manage Users</small>
|
||||
</div>
|
||||
<div class="dropdown-shortcuts-item col">
|
||||
<span class="dropdown-shortcuts-icon bg-label-secondary rounded-circle mb-2">
|
||||
<i class="bx bx-check-shield fs-4"></i>
|
||||
</span>
|
||||
<a href="app-access-roles.html" class="stretched-link">Role Management</a>
|
||||
<small class="text-muted mb-0">Permission</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row row-bordered overflow-visible g-0">
|
||||
<div class="dropdown-shortcuts-item col">
|
||||
<span class="dropdown-shortcuts-icon bg-label-secondary rounded-circle mb-2">
|
||||
<i class="bx bx-pie-chart-alt-2 fs-4"></i>
|
||||
</span>
|
||||
<a href="index.html" class="stretched-link">Dashboard</a>
|
||||
<small class="text-muted mb-0">User Profile</small>
|
||||
</div>
|
||||
<div class="dropdown-shortcuts-item col">
|
||||
<span class="dropdown-shortcuts-icon bg-label-secondary rounded-circle mb-2">
|
||||
<i class="bx bx-cog fs-4"></i>
|
||||
</span>
|
||||
<a href="pages-account-settings-account.html" class="stretched-link">Setting</a>
|
||||
<small class="text-muted mb-0">Account Settings</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row row-bordered overflow-visible g-0">
|
||||
<div class="dropdown-shortcuts-item col">
|
||||
<span class="dropdown-shortcuts-icon bg-label-secondary rounded-circle mb-2">
|
||||
<i class="bx bx-help-circle fs-4"></i>
|
||||
</span>
|
||||
<a href="pages-help-center-landing.html" class="stretched-link">Help Center</a>
|
||||
<small class="text-muted mb-0">FAQs & Articles</small>
|
||||
</div>
|
||||
<div class="dropdown-shortcuts-item col">
|
||||
<span class="dropdown-shortcuts-icon bg-label-secondary rounded-circle mb-2">
|
||||
<i class="bx bx-window-open fs-4"></i>
|
||||
</span>
|
||||
<a href="modal-examples.html" class="stretched-link">Modals</a>
|
||||
<small class="text-muted mb-0">Useful Popups</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<!-- Quick links --%>
|
||||
|
||||
<%-- Notification -->
|
||||
<li class="nav-item dropdown-notifications navbar-dropdown dropdown me-3 me-xl-1">
|
||||
<a
|
||||
class="nav-link dropdown-toggle hide-arrow"
|
||||
href="javascript:void(0);"
|
||||
data-bs-toggle="dropdown"
|
||||
data-bs-auto-close="outside"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<i class="bx bx-bell bx-sm"></i>
|
||||
<span class="badge bg-danger rounded-pill badge-notifications">5</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end py-0">
|
||||
<li class="dropdown-menu-header border-bottom">
|
||||
<div class="dropdown-header d-flex align-items-center py-3">
|
||||
<h5 class="text-body mb-0 me-auto">Notification</h5>
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
class="dropdown-notifications-all text-body"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="Mark all as read"
|
||||
><i class="bx fs-4 bx-envelope-open"></i
|
||||
></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="dropdown-notifications-list scrollable-container">
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item list-group-item-action dropdown-notifications-item">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar">
|
||||
<img src="<c:url value="/resources/img/avatars/1.png"/>" alt class="w-px-40 h-auto rounded-circle" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-1">Congratulation Lettie 🎉</h6>
|
||||
<p class="mb-0">Won the monthly best seller gold badge</p>
|
||||
<small class="text-muted">1h ago</small>
|
||||
</div>
|
||||
<div class="flex-shrink-0 dropdown-notifications-actions">
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-read"
|
||||
><span class="badge badge-dot"></span
|
||||
></a>
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-archive"
|
||||
><span class="bx bx-x"></span
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item list-group-item-action dropdown-notifications-item">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar">
|
||||
<span class="avatar-initial rounded-circle bg-label-danger">CF</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-1">Charles Franklin</h6>
|
||||
<p class="mb-0">Accepted your connection</p>
|
||||
<small class="text-muted">12hr ago</small>
|
||||
</div>
|
||||
<div class="flex-shrink-0 dropdown-notifications-actions">
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-read"
|
||||
><span class="badge badge-dot"></span
|
||||
></a>
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-archive"
|
||||
><span class="bx bx-x"></span
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item list-group-item-action dropdown-notifications-item marked-as-read">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar">
|
||||
<img src="<c:url value="/resources/img/avatars/2.png"/>" alt class="w-px-40 h-auto rounded-circle" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-1">New Message ✉️</h6>
|
||||
<p class="mb-0">You have new message from Natalie</p>
|
||||
<small class="text-muted">1h ago</small>
|
||||
</div>
|
||||
<div class="flex-shrink-0 dropdown-notifications-actions">
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-read"
|
||||
><span class="badge badge-dot"></span
|
||||
></a>
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-archive"
|
||||
><span class="bx bx-x"></span
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item list-group-item-action dropdown-notifications-item">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar">
|
||||
<span class="avatar-initial rounded-circle bg-label-success"
|
||||
><i class="bx bx-cart"></i
|
||||
></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-1">Whoo! You have new order 🛒</h6>
|
||||
<p class="mb-0">ACME Inc. made new order $1,154</p>
|
||||
<small class="text-muted">1 day ago</small>
|
||||
</div>
|
||||
<div class="flex-shrink-0 dropdown-notifications-actions">
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-read"
|
||||
><span class="badge badge-dot"></span
|
||||
></a>
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-archive"
|
||||
><span class="bx bx-x"></span
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item list-group-item-action dropdown-notifications-item marked-as-read">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar">
|
||||
<img src="<c:url value="/resources/img/avatars/9.png"/>" alt class="w-px-40 h-auto rounded-circle" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-1">Application has been approved 🚀</h6>
|
||||
<p class="mb-0">Your ABC project application has been approved.</p>
|
||||
<small class="text-muted">2 days ago</small>
|
||||
</div>
|
||||
<div class="flex-shrink-0 dropdown-notifications-actions">
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-read"
|
||||
><span class="badge badge-dot"></span
|
||||
></a>
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-archive"
|
||||
><span class="bx bx-x"></span
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item list-group-item-action dropdown-notifications-item marked-as-read">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar">
|
||||
<span class="avatar-initial rounded-circle bg-label-success"
|
||||
><i class="bx bx-pie-chart-alt"></i
|
||||
></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-1">Monthly report is generated</h6>
|
||||
<p class="mb-0">July monthly financial report is generated</p>
|
||||
<small class="text-muted">3 days ago</small>
|
||||
</div>
|
||||
<div class="flex-shrink-0 dropdown-notifications-actions">
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-read"
|
||||
><span class="badge badge-dot"></span
|
||||
></a>
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-archive"
|
||||
><span class="bx bx-x"></span
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item list-group-item-action dropdown-notifications-item marked-as-read">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar">
|
||||
<img src="<c:url value="/resources/img/avatars/5.png"/>" alt class="w-px-40 h-auto rounded-circle" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-1">Send connection request</h6>
|
||||
<p class="mb-0">Peter sent you connection request</p>
|
||||
<small class="text-muted">4 days ago</small>
|
||||
</div>
|
||||
<div class="flex-shrink-0 dropdown-notifications-actions">
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-read"
|
||||
><span class="badge badge-dot"></span
|
||||
></a>
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-archive"
|
||||
><span class="bx bx-x"></span
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item list-group-item-action dropdown-notifications-item">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar">
|
||||
<img src="<c:url value="/resources/img/avatars/6.png"/>" alt class="w-px-40 h-auto rounded-circle" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-1">New message from Jane</h6>
|
||||
<p class="mb-0">Your have new message from Jane</p>
|
||||
<small class="text-muted">5 days ago</small>
|
||||
</div>
|
||||
<div class="flex-shrink-0 dropdown-notifications-actions">
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-read"
|
||||
><span class="badge badge-dot"></span
|
||||
></a>
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-archive"
|
||||
><span class="bx bx-x"></span
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item list-group-item-action dropdown-notifications-item marked-as-read">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar">
|
||||
<span class="avatar-initial rounded-circle bg-label-warning"
|
||||
><i class="bx bx-error"></i
|
||||
></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-1">CPU is running high</h6>
|
||||
<p class="mb-0">CPU Utilization Percent is currently at 88.63%,</p>
|
||||
<small class="text-muted">5 days ago</small>
|
||||
</div>
|
||||
<div class="flex-shrink-0 dropdown-notifications-actions">
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-read"
|
||||
><span class="badge badge-dot"></span
|
||||
></a>
|
||||
<a href="javascript:void(0)" class="dropdown-notifications-archive"
|
||||
><span class="bx bx-x"></span
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown-menu-footer border-top">
|
||||
<a href="javascript:void(0);" class="dropdown-item d-flex justify-content-center p-3">
|
||||
View all notifications
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!--/ Notification --%>
|
||||
<!-- User -->
|
||||
<li class="nav-item navbar-dropdown dropdown-user dropdown">
|
||||
<a class="nav-link dropdown-toggle hide-arrow" href="javascript:void(0);" data-bs-toggle="dropdown">
|
||||
<div class="avatar avatar-online">
|
||||
<img src="<c:url value="/resources/img/avatars/1.png"/>" alt class="w-px-40 h-auto rounded-circle" />
|
||||
</div>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li>
|
||||
<a class="dropdown-item" href="pages-account-settings-account.html">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar avatar-online">
|
||||
<img src="<c:url value="/resources/img/avatars/1.png"/>" alt class="w-px-40 h-auto rounded-circle" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<span class="fw-semibold d-block">${currentUser.name}</span>
|
||||
<small class="text-muted">${currentUser.account}</small>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="dropdown-divider"></div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="pages-profile-user.html">
|
||||
<i class="bx bx-user me-2"></i>
|
||||
<span class="align-middle">프로필</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="pages-account-settings-account.html">
|
||||
<i class="bx bx-cog me-2"></i>
|
||||
<span class="align-middle">설정</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="dropdown-divider"></div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="pages-help-center-landing.html">
|
||||
<i class="bx bx-support me-2"></i>
|
||||
<span class="align-middle">Help</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="dropdown-divider"></div>
|
||||
</li>
|
||||
<li onclick="logout();">
|
||||
<a class="dropdown-item">
|
||||
<i class="bx bx-power-off me-2"></i>
|
||||
<span class="align-middle">로그아웃</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!--/ User -->
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<%-- Search Small Screens -->
|
||||
<div class="navbar-search-wrapper search-input-wrapper d-none">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control search-input container-xxl border-0"
|
||||
placeholder="Search..."
|
||||
aria-label="Search..."
|
||||
/>
|
||||
<i class="bx bx-x bx-sm search-toggler cursor-pointer"></i>
|
||||
</div --%>
|
||||
</nav>
|
||||
|
||||
<!-- / Navbar -->
|
||||
<c:set var="functions" scope="request">${functions}
|
||||
function setPageTitle(pageTitle) {
|
||||
$("#pageTitle").html(pageTitle);
|
||||
}</c:set>
|
@ -0,0 +1,96 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<!-- Menu -->
|
||||
<aside id="layout-menu" class="layout-menu menu-vertical menu bg-menu-theme">
|
||||
<div class="app-brand demo">
|
||||
<a href="javascript:wctx.home();" class="app-brand-link">
|
||||
<span class="app-brand-logo demo">
|
||||
<svg
|
||||
width="25"
|
||||
viewBox="0 0 25 42"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<defs>
|
||||
<path
|
||||
d="M13.7918663,0.358365126 L3.39788168,7.44174259 C0.566865006,9.69408886 -0.379795268,12.4788597 0.557900856,15.7960551 C0.68998853,16.2305145 1.09562888,17.7872135 3.12357076,19.2293357 C3.8146334,19.7207684 5.32369333,20.3834223 7.65075054,21.2172976 L7.59773219,21.2525164 L2.63468769,24.5493413 C0.445452254,26.3002124 0.0884951797,28.5083815 1.56381646,31.1738486 C2.83770406,32.8170431 5.20850219,33.2640127 7.09180128,32.5391577 C8.347334,32.0559211 11.4559176,30.0011079 16.4175519,26.3747182 C18.0338572,24.4997857 18.6973423,22.4544883 18.4080071,20.2388261 C17.963753,17.5346866 16.1776345,15.5799961 13.0496516,14.3747546 L10.9194936,13.4715819 L18.6192054,7.984237 L13.7918663,0.358365126 Z"
|
||||
id="path-1"
|
||||
></path>
|
||||
<path
|
||||
d="M5.47320593,6.00457225 C4.05321814,8.216144 4.36334763,10.0722806 6.40359441,11.5729822 C8.61520715,12.571656 10.0999176,13.2171421 10.8577257,13.5094407 L15.5088241,14.433041 L18.6192054,7.984237 C15.5364148,3.11535317 13.9273018,0.573395879 13.7918663,0.358365126 C13.5790555,0.511491653 10.8061687,2.3935607 5.47320593,6.00457225 Z"
|
||||
id="path-3"
|
||||
></path>
|
||||
<path
|
||||
d="M7.50063644,21.2294429 L12.3234468,23.3159332 C14.1688022,24.7579751 14.397098,26.4880487 13.008334,28.506154 C11.6195701,30.5242593 10.3099883,31.790241 9.07958868,32.3040991 C5.78142938,33.4346997 4.13234973,34 4.13234973,34 C4.13234973,34 2.75489982,33.0538207 2.37032616e-14,31.1614621 C-0.55822714,27.8186216 -0.55822714,26.0572515 -4.05231404e-15,25.8773518 C0.83734071,25.6075023 2.77988457,22.8248993 3.3049379,22.52991 C3.65497346,22.3332504 5.05353963,21.8997614 7.50063644,21.2294429 Z"
|
||||
id="path-4"
|
||||
></path>
|
||||
<path
|
||||
d="M20.6,7.13333333 L25.6,13.8 C26.2627417,14.6836556 26.0836556,15.9372583 25.2,16.6 C24.8538077,16.8596443 24.4327404,17 24,17 L14,17 C12.8954305,17 12,16.1045695 12,15 C12,14.5672596 12.1403557,14.1461923 12.4,13.8 L17.4,7.13333333 C18.0627417,6.24967773 19.3163444,6.07059163 20.2,6.73333333 C20.3516113,6.84704183 20.4862915,6.981722 20.6,7.13333333 Z"
|
||||
id="path-5"
|
||||
></path>
|
||||
</defs>
|
||||
<g id="g-app-brand" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Brand-Logo" transform="translate(-27.000000, -15.000000)">
|
||||
<g id="Icon" transform="translate(27.000000, 15.000000)">
|
||||
<g id="Mask" transform="translate(0.000000, 8.000000)">
|
||||
<mask id="mask-2" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<use fill="#696cff" xlink:href="#path-1"></use>
|
||||
<g id="Path-3" mask="url(#mask-2)">
|
||||
<use fill="#696cff" xlink:href="#path-3"></use>
|
||||
<use fill-opacity="0.2" fill="#FFFFFF" xlink:href="#path-3"></use>
|
||||
</g>
|
||||
<g id="Path-4" mask="url(#mask-2)">
|
||||
<use fill="#696cff" xlink:href="#path-4"></use>
|
||||
<use fill-opacity="0.2" fill="#FFFFFF" xlink:href="#path-4"></use>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="Triangle"
|
||||
transform="translate(19.000000, 11.000000) rotate(-300.000000) translate(-19.000000, -11.000000) "
|
||||
>
|
||||
<use fill="#696cff" xlink:href="#path-5"></use>
|
||||
<use fill-opacity="0.2" fill="#FFFFFF" xlink:href="#path-5"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="app-brand-text demo menu-text fw-bolder ms-2">XIT Base</span>
|
||||
</a>
|
||||
|
||||
<a href="javascript:void(0);" class="layout-menu-toggle menu-link text-large ms-auto">
|
||||
<i class="bx bx-chevron-left bx-sm align-middle"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-inner-shadow"></div>
|
||||
|
||||
<ul id="menus" class="menu-inner py-1">
|
||||
</ul>
|
||||
</aside>
|
||||
<!-- / Menu -->
|
||||
<c:set var="userMenus" scope="request">let userMenus = ${userMenus};
|
||||
<%--if (menus.length < 1)
|
||||
menus = [
|
||||
{"id":0, "name": "사용자", "url":"/user/main.do", "parentID":null, "description":"사용자 관리", "imagePath":null, "displayWindow":"_self"},
|
||||
{"id":1, "name": "권한", "url":null, "parentID":null, "description":"권한 관리", "imagePath":null, "displayWindow":"_self",
|
||||
"children":[
|
||||
{"id":2, "name": "권한 설정", "url":"/authority/list.do", "parentID":1, "description":"권한 관리", "imagePath":null, "displayWindow":"_self"},
|
||||
{"id":3, "name": "액션 설정", "url":"/authority/action/list.do", "parentID":1, "description":"액션 관리", "imagePath":null, "displayWindow":"_self"},
|
||||
]
|
||||
},
|
||||
{"id":4, "name": "메뉴", "url":"/menu/list.do", "parentID":null, "description":"메뉴 관리", "imagePath":null, "displayWindow":"_self"}
|
||||
];--%>
|
||||
function setUserMenus(menus) {
|
||||
let menuSupport = new MenuSupport("#layout-menu").setMenuInfo(menus).setActive(wctx.current());
|
||||
let currentMenu = menuSupport.getMenu(wctx.current());
|
||||
if (currentMenu)
|
||||
setPageTitle(currentMenu.name);
|
||||
}
|
||||
|
||||
setUserMenus(userMenus);
|
||||
</c:set>
|
@ -0,0 +1,30 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<jsp:include page="/WEB-INF/jsp/include/head.jsp" />
|
||||
<body>
|
||||
<!-- Layout wrapper -->
|
||||
<div class="layout-wrapper layout-content-navbar">
|
||||
<div class="layout-container">
|
||||
<jsp:include page="/WEB-INF/jsp/include/userMenus.jsp" />
|
||||
<!-- Layout container -->
|
||||
<div class="layout-page">
|
||||
<jsp:include page="/WEB-INF/jsp/include/top.jsp" />
|
||||
|
||||
</div>
|
||||
<!-- / Layout page -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Layout wrapper -->
|
||||
|
||||
<jsp:include page="/WEB-INF/jsp/include/tail.jsp" />
|
||||
<script >
|
||||
${functions}
|
||||
${userMenus}
|
||||
|
||||
$(function(){
|
||||
${onload}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,157 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<jsp:include page="/WEB-INF/jsp/include/head.jsp" />
|
||||
<body>
|
||||
<!-- Content -->
|
||||
|
||||
<div class="authentication-wrapper authentication-cover">
|
||||
<div class="authentication-inner row m-0">
|
||||
<!-- /Left Text -->
|
||||
<div class="d-none d-lg-flex col-lg-7 col-xl-8 align-items-center p-5">
|
||||
<div class="w-100 d-flex justify-content-center">
|
||||
<img
|
||||
src="<c:url value="/resources/img/illustrations/boy-with-rocket-light.png"/>"
|
||||
class="img-fluid"
|
||||
alt="Login image"
|
||||
width="700"
|
||||
data-app-dark-img="illustrations/boy-with-rocket-dark.png"
|
||||
data-app-light-img="illustrations/boy-with-rocket-light.png"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Left Text -->
|
||||
|
||||
<!-- Login -->
|
||||
<div class="d-flex col-12 col-lg-5 col-xl-4 align-items-center authentication-bg p-sm-5 p-4" style="background-color:white;">
|
||||
<div class="w-px-400 mx-auto">
|
||||
<!-- Logo -->
|
||||
<div class="app-brand mb-5">
|
||||
<a href="index.html" class="app-brand-link gap-2">
|
||||
<span class="app-brand-logo demo">
|
||||
<svg
|
||||
width="25"
|
||||
viewBox="0 0 25 42"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<defs>
|
||||
<path
|
||||
d="M13.7918663,0.358365126 L3.39788168,7.44174259 C0.566865006,9.69408886 -0.379795268,12.4788597 0.557900856,15.7960551 C0.68998853,16.2305145 1.09562888,17.7872135 3.12357076,19.2293357 C3.8146334,19.7207684 5.32369333,20.3834223 7.65075054,21.2172976 L7.59773219,21.2525164 L2.63468769,24.5493413 C0.445452254,26.3002124 0.0884951797,28.5083815 1.56381646,31.1738486 C2.83770406,32.8170431 5.20850219,33.2640127 7.09180128,32.5391577 C8.347334,32.0559211 11.4559176,30.0011079 16.4175519,26.3747182 C18.0338572,24.4997857 18.6973423,22.4544883 18.4080071,20.2388261 C17.963753,17.5346866 16.1776345,15.5799961 13.0496516,14.3747546 L10.9194936,13.4715819 L18.6192054,7.984237 L13.7918663,0.358365126 Z"
|
||||
id="path-1"
|
||||
></path>
|
||||
<path
|
||||
d="M5.47320593,6.00457225 C4.05321814,8.216144 4.36334763,10.0722806 6.40359441,11.5729822 C8.61520715,12.571656 10.0999176,13.2171421 10.8577257,13.5094407 L15.5088241,14.433041 L18.6192054,7.984237 C15.5364148,3.11535317 13.9273018,0.573395879 13.7918663,0.358365126 C13.5790555,0.511491653 10.8061687,2.3935607 5.47320593,6.00457225 Z"
|
||||
id="path-3"
|
||||
></path>
|
||||
<path
|
||||
d="M7.50063644,21.2294429 L12.3234468,23.3159332 C14.1688022,24.7579751 14.397098,26.4880487 13.008334,28.506154 C11.6195701,30.5242593 10.3099883,31.790241 9.07958868,32.3040991 C5.78142938,33.4346997 4.13234973,34 4.13234973,34 C4.13234973,34 2.75489982,33.0538207 2.37032616e-14,31.1614621 C-0.55822714,27.8186216 -0.55822714,26.0572515 -4.05231404e-15,25.8773518 C0.83734071,25.6075023 2.77988457,22.8248993 3.3049379,22.52991 C3.65497346,22.3332504 5.05353963,21.8997614 7.50063644,21.2294429 Z"
|
||||
id="path-4"
|
||||
></path>
|
||||
<path
|
||||
d="M20.6,7.13333333 L25.6,13.8 C26.2627417,14.6836556 26.0836556,15.9372583 25.2,16.6 C24.8538077,16.8596443 24.4327404,17 24,17 L14,17 C12.8954305,17 12,16.1045695 12,15 C12,14.5672596 12.1403557,14.1461923 12.4,13.8 L17.4,7.13333333 C18.0627417,6.24967773 19.3163444,6.07059163 20.2,6.73333333 C20.3516113,6.84704183 20.4862915,6.981722 20.6,7.13333333 Z"
|
||||
id="path-5"
|
||||
></path>
|
||||
</defs>
|
||||
<g id="g-app-brand" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Brand-Logo" transform="translate(-27.000000, -15.000000)">
|
||||
<g id="Icon" transform="translate(27.000000, 15.000000)">
|
||||
<g id="Mask" transform="translate(0.000000, 8.000000)">
|
||||
<mask id="mask-2" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<use fill="#696cff" xlink:href="#path-1"></use>
|
||||
<g id="Path-3" mask="url(#mask-2)">
|
||||
<use fill="#696cff" xlink:href="#path-3"></use>
|
||||
<use fill-opacity="0.2" fill="#FFFFFF" xlink:href="#path-3"></use>
|
||||
</g>
|
||||
<g id="Path-4" mask="url(#mask-2)">
|
||||
<use fill="#696cff" xlink:href="#path-4"></use>
|
||||
<use fill-opacity="0.2" fill="#FFFFFF" xlink:href="#path-4"></use>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="Triangle"
|
||||
transform="translate(19.000000, 11.000000) rotate(-300.000000) translate(-19.000000, -11.000000) "
|
||||
>
|
||||
<use fill="#696cff" xlink:href="#path-5"></use>
|
||||
<use fill-opacity="0.2" fill="#FFFFFF" xlink:href="#path-5"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="app-brand-text demo text-body fw-bolder">XIT Base Example</span>
|
||||
</a>
|
||||
</div>
|
||||
<!-- /Logo -->
|
||||
<h4 class="mb-2">반갑습니다, XIT Base입니다. 👋</h4>
|
||||
<p class="mb-4">이 사이트는 XIT Base로 만든 예제 사이트 입니다.</p>
|
||||
|
||||
<div id="formAuthentication" class="mb-3">
|
||||
<div class="mb-3">
|
||||
<label for="userId" class="form-label">아이디</label>
|
||||
<input id="userId" type="text" required class="form-control" placeholder="아이디를 입력하십시오." autofocus />
|
||||
</div>
|
||||
<div class="mb-3 form-password-toggle">
|
||||
<div class="d-flex justify-content-between">
|
||||
<label class="form-label" for="password">비밀번호</label>
|
||||
<a href="auth-forgot-password-cover.html">
|
||||
<small>비밀번호 찾기</small>
|
||||
</a>
|
||||
</div>
|
||||
<div class="input-group input-group-merge">
|
||||
<input id="password" type="password" required class="form-control" placeholder="비밀번호를 입력하십시오." aria-describedby="password" />
|
||||
<span class="input-group-text cursor-pointer"><i class="bx bx-hide"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary d-grid w-100" onclick="login();">로그인</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Login -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- / Content -->
|
||||
<jsp:include page="/WEB-INF/jsp/include/tail.jsp" />
|
||||
<!-- Main JS -->
|
||||
<script>
|
||||
${functions}
|
||||
function login() {
|
||||
if (!$("#formAuthentication input").validInputs()) return;
|
||||
|
||||
var params = {
|
||||
account:$("#userId").val(),
|
||||
password:$("#password").val(),
|
||||
institute:"default"
|
||||
};
|
||||
json.post({
|
||||
url:wctx.url("/login.do"),
|
||||
data:params,
|
||||
success:function(resp) {
|
||||
if (resp.authenticated) {
|
||||
if (resp.message)
|
||||
dialog.alert(resp.message);
|
||||
|
||||
wctx.home();
|
||||
} else {
|
||||
dialog.alert({
|
||||
content:resp.reason,
|
||||
onClose:() => $("#userId").focus()
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(function(){
|
||||
$("#formAuthentication input").onEnterPress(login);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,56 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<link rel="stylesheet" href="<c:url value="/resources/3rd-party/sneat/libs/jstree/jstree.css"/>" /--%>
|
||||
<div id="_url-tree" class="main-left d-flex flex-column flex-grow-1">
|
||||
<div class="d-flex justify-content-between" style="padding-top:.5em; padding-bottom:.5em; border-top:1px solid #dfdfdf; border-bottom:1px solid #dfdfdf;">
|
||||
<span>
|
||||
<button id="_urlToggler" onclick="_toggleURLs();" class="btn btn-primary"></button>
|
||||
</span>
|
||||
</div>
|
||||
<div id="_urlTree" style="padding-top:1em; height:37em; overflow:auto;">
|
||||
</div>
|
||||
</div>
|
||||
<script src="<c:url value="/resources/3rd-party/sneat/libs/jstree/jstree.js"/>"></script>
|
||||
<script src="<c:url value="/resources/3rd-party/jstree/jstree-support.js"/>"></script>
|
||||
<script type="text/javascript">
|
||||
var _multiple = ${multiple},
|
||||
_urlSupport = treeSupport({
|
||||
selector:"#_urlTree",
|
||||
trace:wctx.trace,
|
||||
plugins: _multiple ? ["checkbox"] : [],
|
||||
core:{check_callback:true,
|
||||
multiple:_multiple
|
||||
// themes:{name:"proton"}
|
||||
},
|
||||
checkbox:{
|
||||
whole_node:false,
|
||||
tie_selection:false
|
||||
}
|
||||
});
|
||||
|
||||
function getSelectedURL() {
|
||||
var selected = _multiple ? _urlSupport.checkedNodes() : _urlSupport.selectedNodes();
|
||||
if (selected.length < 1)
|
||||
return dialog.alert("URL을 선택하십시오.");
|
||||
|
||||
if (_multiple)
|
||||
return selected;
|
||||
else
|
||||
return selected[0];
|
||||
}
|
||||
|
||||
function _toggleURLs() {
|
||||
$("#_urlToggler").text(_urlSupport.toggleFolding() == "collapsed" ? "+ 펼치기" : "- 닫기");
|
||||
}
|
||||
|
||||
var urls = ${urls};
|
||||
|
||||
_urlSupport.setData(treeHtml(urls, {
|
||||
id:function(e){return e.url;},
|
||||
text:function(e){
|
||||
return e.name == e.url ? e.name : e.name + " (" + e.url + ")";
|
||||
}
|
||||
}));
|
||||
|
||||
$("#_urlToggler").text(_urlSupport._folding == "collapsed" ? "+ 펼치기" : "- 닫기");
|
||||
</script>
|
@ -0,0 +1,114 @@
|
||||
class ActionGroupControl {
|
||||
constructor(linked) {
|
||||
this.linked = false !== linked;
|
||||
this.groups = new DatasetControl({
|
||||
prefix:"group",
|
||||
prefixName:"기능그룹",
|
||||
keymapper:info => info.GRP_ID,
|
||||
dataGetter:obj => obj.groupList,
|
||||
formats: {
|
||||
REG_DT:datetimeFormat
|
||||
},
|
||||
urls:{
|
||||
load:wctx.url("/actionGroup/list.do"),
|
||||
getInfo:wctx.url("/actionGroup/info.do"),
|
||||
create:wctx.url("/actionGroup/create.do"),
|
||||
update:wctx.url("/actionGroup/update.do"),
|
||||
remove:wctx.url("/actionGroup/remove.do")
|
||||
}
|
||||
});
|
||||
|
||||
this.actions = new DatasetControl({
|
||||
prefix:"action",
|
||||
prefixName:"기능",
|
||||
keymapper:info => info.GRP_ID + "-" + info.ACTION,
|
||||
dataGetter:obj => obj.actionList,
|
||||
formats: {
|
||||
REG_DT:datetimeFormat
|
||||
},
|
||||
urls:{
|
||||
load:wctx.url("/actionGroup/action/list.do")
|
||||
}
|
||||
});
|
||||
this.actions.urls.load = wctx.url("/actionGroup/action/list.do")
|
||||
|
||||
this.groups.onDatasetChange = obj => this.onGroupListChange(obj);
|
||||
this.groups.onCurrentChange = item => {
|
||||
this.onCurrentGroupChange(item);
|
||||
if (!this.linked) return;
|
||||
|
||||
let row = item ? item.data : null;
|
||||
if (row) {
|
||||
this.actions.query.groupIDs = row.GRP_ID;
|
||||
this.actions.load();
|
||||
} else
|
||||
this.actions.dataset.clear();
|
||||
};
|
||||
this.groups.onSelectionChange = selected => this.onGroupSelect(selected);
|
||||
|
||||
this.actions.onDatasetChange = obj => this.onActionListChange(obj);
|
||||
this.actions.onCurrentChange = item => this.onCurrentActionChange(item);
|
||||
this.actions.onSelectionChange = selected => this.onActionSelect(selected);
|
||||
}
|
||||
|
||||
onGroupListChange(obj) {}
|
||||
|
||||
onCurrentGroupChange(item) {}
|
||||
|
||||
onGroupSelect(selected) {}
|
||||
|
||||
async selectActionGroup() {
|
||||
return new Promise((resolve, reject) => {
|
||||
ajax.get({
|
||||
url:wctx.url("/actionGroup/select.do"),
|
||||
data:{multiple:true},
|
||||
success:resp => {
|
||||
dialog.open({
|
||||
title:"기능그룹 선택",
|
||||
content:resp,
|
||||
getData:() => {return getSelectedActionGroup();},
|
||||
onOK:(selected) => resolve(selected)
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onActionListChange(obj) {}
|
||||
|
||||
onCurrentActionChange(item) {}
|
||||
|
||||
onActionSelect(selected) {}
|
||||
|
||||
async addActions() {
|
||||
let actions = await selectURL(true);
|
||||
actions = actions.filter(a => "/" == a || a.endsWith(".do"));
|
||||
let groupID = this.groups.dataset.getCurrent().GRP_ID;
|
||||
json.post({
|
||||
url:wctx.url("/actionGroup/action/add.do"),
|
||||
data:{
|
||||
groupID:groupID,
|
||||
actions:actions.join(",")
|
||||
},
|
||||
success:resp => {
|
||||
this.actions._load();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
removeActions() {
|
||||
let selected = this.actions.dataset.getDataset("selected").map(info => info.ACTION);
|
||||
let groupID = this.groups.dataset.getCurrent().GRP_ID;
|
||||
json.post({
|
||||
url:wctx.url("/actionGroup/action/remove.do"),
|
||||
data:{
|
||||
groupID:groupID,
|
||||
actions:selected.join(",")
|
||||
},
|
||||
success:resp => {
|
||||
if (resp.saved)
|
||||
this.actions._load();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,188 @@
|
||||
class AuthorityControl {
|
||||
constructor() {
|
||||
this.authorities = new DatasetControl({
|
||||
prefix:"authority",
|
||||
prefixName:"권한",
|
||||
keymapper:info => info.AUTH_ID,
|
||||
dataGetter:obj => obj.authorityList,
|
||||
formats: {
|
||||
REG_DT:datetimeFormat
|
||||
}
|
||||
});
|
||||
|
||||
this.authorities.isBuiltIn = (info) => {
|
||||
let current = info || this.authorities.getCurrent();
|
||||
return current && current.AUTH_TYPE < 2;
|
||||
};
|
||||
|
||||
this.authorities.isImplicit = (info) => {
|
||||
let current = info || this.authorities.getCurrent();
|
||||
return current && current.AUTH_TYPE === 1;
|
||||
};
|
||||
|
||||
this.authorities.isAdmin = (info) => {
|
||||
let current = info || this.authorities.getCurrent();
|
||||
return current && current.AUTH_TYPE === 0;
|
||||
};
|
||||
|
||||
this.users = new DatasetControl({
|
||||
prefix:"user",
|
||||
prefixName:"사용자",
|
||||
keymapper:info => info.AUTH_ID + "-" + info.USER_ID,
|
||||
dataGetter:obj => obj.userList,
|
||||
formats: {
|
||||
REG_DT:datetimeFormat
|
||||
},
|
||||
urls:{
|
||||
load:wctx.url("/authority/user/list.do")
|
||||
}
|
||||
});
|
||||
|
||||
this.actions = new DatasetControl({
|
||||
prefix:"action",
|
||||
prefixName:"기능 그룹",
|
||||
keymapper:info => info.AUTH_ID + "-" + info.GRP_ID,
|
||||
dataGetter:obj => obj.actionList,
|
||||
formats: {
|
||||
REG_DT:datetimeFormat
|
||||
},
|
||||
urls:{
|
||||
load:wctx.url("/authority/action/list.do")
|
||||
}
|
||||
});
|
||||
|
||||
this.linkedList = "users";
|
||||
|
||||
this.authorities.onDatasetChange = obj => this.onAuthorityListChange(obj);
|
||||
this.authorities.onCurrentChange = item => {
|
||||
this.onCurrentAuthorityChange(item);
|
||||
let info = item ? item.data : null;
|
||||
this.getLinkedList(this.linkedList, info);
|
||||
};
|
||||
this.authorities.onSelectionChange = selected => this.onAuthoritySelect(selected);
|
||||
|
||||
this.users.onDatasetChange = obj => this.onUserListChange(obj);
|
||||
this.users.onCurrentChange = item => this.onCurrentUserChange(item);
|
||||
this.users.onSelectionChange = selected => this.onUserSelect(selected);
|
||||
|
||||
this.actions.onDatasetChange = obj => this.onActionListChange(obj);
|
||||
this.actions.onCurrentChange = item => this.onCurrentActionChange(item);
|
||||
this.actions.onSelectionChange = selected => this.onActionSelect(selected);
|
||||
}
|
||||
|
||||
getLinkedList(linked, info) {
|
||||
if (!info)
|
||||
info = this.authorities.getCurrent();
|
||||
switch (this.linkedList = linked) {
|
||||
case "users":
|
||||
if (info && !this.authorities.isImplicit(info)) {
|
||||
if (this.users.query.authIDs == info.AUTH_ID) return;
|
||||
this.users.query.authIDs = info.AUTH_ID;
|
||||
this.users.load();
|
||||
} else {
|
||||
this.users.query.authIDs = info.AUTH_ID;
|
||||
this.users.dataset.clear();
|
||||
}
|
||||
break;
|
||||
case "actions":
|
||||
if (info && !this.authorities.isAdmin(info)) {
|
||||
if (this.actions.query.authIDs == info.AUTH_ID) return;
|
||||
this.actions.query.authIDs = info.AUTH_ID;
|
||||
this.actions.load();
|
||||
} else {
|
||||
this.actions.query.authIDs = info.AUTH_ID;
|
||||
this.actions.dataset.clear();
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
onAuthorityListChange(obj) {}
|
||||
|
||||
onCurrentAuthorityChange(item) {}
|
||||
|
||||
onAuthoritySelect(selected) {}
|
||||
|
||||
removeAuthorities() {
|
||||
let authIDs = this.authorities.dataset.getKeys("selected");
|
||||
this.authorities.remove({authIDs:authIDs.join(",")});
|
||||
}
|
||||
|
||||
onUserListChange(obj) {}
|
||||
|
||||
onCurrentUserChange(item) {}
|
||||
|
||||
onUserSelect(selected) {}
|
||||
|
||||
onActionListChange(obj) {}
|
||||
|
||||
onCurrentActionChange(item) {}
|
||||
|
||||
onActionSelect(selected) {}
|
||||
|
||||
async addUsers() {
|
||||
let userIDs = await new UserControl().selectUser(true);
|
||||
let authID = this.authorities.dataset.getCurrent().AUTH_ID;
|
||||
json.post({
|
||||
url:wctx.url("/authority/user/add.do"),
|
||||
data:{
|
||||
authID:authID,
|
||||
userIDs:userIDs.join(",")
|
||||
},
|
||||
success:resp => {
|
||||
if (resp.saved)
|
||||
this.users._load();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
removeUsers() {
|
||||
let selected = this.users.dataset.getDataset("selected").map(info => info.USER_ID);
|
||||
let authID = this.authorities.dataset.getCurrent().AUTH_ID;
|
||||
json.post({
|
||||
url:wctx.url("/authority/user/remove.do"),
|
||||
data:{
|
||||
authID:authID,
|
||||
userIDs:selected.join(",")
|
||||
},
|
||||
success:resp => {
|
||||
if (resp.saved)
|
||||
this.users._load();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async addActions() {
|
||||
let actions = await new ActionGroupControl(false).selectActionGroup(true);
|
||||
let authID = this.authorities.dataset.getCurrent().AUTH_ID;
|
||||
|
||||
json.post({
|
||||
url:wctx.url("/authority/action/add.do"),
|
||||
data:{
|
||||
authID:authID,
|
||||
groupIDs:actions.join(",")
|
||||
},
|
||||
success:resp => {
|
||||
if (resp.saved)
|
||||
this.actions._load();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
removeActions() {
|
||||
let selected = this.actions.dataset.getDataset("selected").map(info => info.GRP_ID);
|
||||
let authID = this.authorities.dataset.getCurrent().AUTH_ID;
|
||||
json.post({
|
||||
url:wctx.url("/authority/action/remove.do"),
|
||||
data:{
|
||||
authID:authID,
|
||||
groupIDs:selected.join(",")
|
||||
},
|
||||
success:resp => {
|
||||
if (resp.saved)
|
||||
this.actions._load();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
class CodeControl {
|
||||
constructor() {
|
||||
this.groups = new DatasetControl({
|
||||
prefix:"group",
|
||||
prefixName:"코드그룹",
|
||||
keymapper:info => info.GRP_ID,
|
||||
dataGetter:obj => obj.groupList,
|
||||
formats: {
|
||||
REG_DT:datetimeFormat
|
||||
},
|
||||
urls:{
|
||||
load:wctx.url("/code/group/list.do"),
|
||||
getInfo:wctx.url("/code/group/info.do"),
|
||||
create:wctx.url("/code/group/create.do"),
|
||||
update:wctx.url("/code/group/update.do"),
|
||||
remove:wctx.url("/code/group/remove.do")
|
||||
}
|
||||
});
|
||||
|
||||
this.codes = new DatasetControl({
|
||||
prefix:"code",
|
||||
prefixName:"코드",
|
||||
keymapper:info => info.CODE,
|
||||
dataGetter:obj => obj.codeList,
|
||||
formats: {
|
||||
REG_DT:datetimeFormat
|
||||
}
|
||||
});
|
||||
|
||||
this.groups.onDatasetChange = obj => this.onGroupListChange(obj);
|
||||
this.groups.onCurrentChange = item => {
|
||||
this.onCurrentGroupChange(item);
|
||||
|
||||
let info = item ? item.data : null;
|
||||
if (info) {
|
||||
this.codes.query.groupIDs = info.GRP_ID;
|
||||
this.codes.load();
|
||||
} else
|
||||
this.codes.dataset.clear();
|
||||
};
|
||||
this.groups.onSelectionChange = selected => this.onGroupSelect(selected);
|
||||
|
||||
this.codes.onDatasetChange = obj => this.onCodeListChange(obj);
|
||||
this.codes.onCurrentChange = item => this.onCurrentCodeChange(item);
|
||||
this.codes.onSelectionChange = selected => this.onCodeSelect(selected);
|
||||
}
|
||||
|
||||
onGroupListChange(obj) {}
|
||||
|
||||
onCurrentGroupChange(item) {}
|
||||
|
||||
onGroupSelect(selected) {}
|
||||
|
||||
newCode() {
|
||||
this.codes.newInfo({GRP_ID:this.groups.getCurrent().GRP_ID})
|
||||
}
|
||||
|
||||
onCodeListChange(obj) {}
|
||||
|
||||
onCurrentCodeChange(item) {}
|
||||
|
||||
onCodeSelect(selected) {}
|
||||
}
|
@ -0,0 +1,174 @@
|
||||
/**메뉴의 생성과 선택 시 동작을 지원한다.
|
||||
*/
|
||||
class MenuSupport {
|
||||
/**새 MenuSupport를 생성한다.
|
||||
* @param selector {string} 메뉴를 담을 컨테이너에 대한 css selector
|
||||
*/
|
||||
constructor(selector) {
|
||||
this._container = document.querySelector(this._selector = selector);
|
||||
this._horizontal = this._container && this._container.classList.contains('menu-horizontal');
|
||||
this._orientation = this._horizontal ? "horizontal" : "vertical";
|
||||
this._template = this._orientation + "-menu-template";
|
||||
this._menuItem = '<li data-key="{menuID}" class="menu-item"><a href="{url}" class="menu-link{toggle}"><i class="menu-icon tf-icons bx bx-layout"></i><div data-i18n="{menuName}">{menuName}</div></a>{menuSub}</li>';
|
||||
this._menuSub = '<ul class="menu-sub">{children}</ul>';
|
||||
this._menus = [];
|
||||
}
|
||||
|
||||
/**메뉴를 생성할 정보를 설정한다.
|
||||
* @param menus {array} 메뉴 정보 배열<br />
|
||||
* 각 메뉴 정보의 레이아웃은 다음과 같다.<br />
|
||||
* {"id":메뉴 아이디, "name":"메뉴 이름", "url":"실행 url", "parentID":"상위 메뉴 아이디", "description":"메뉴 설명", "imagePath":"이미지 경로", "displayWindow":"표시 창", "children":[하위 메뉴 배열]}
|
||||
* @returns MenuSupport
|
||||
*/
|
||||
setMenuInfo(menus) {
|
||||
let setParent = menu => {
|
||||
let children = menu.children || [];
|
||||
if (children.length < 1) return;
|
||||
|
||||
children.forEach(child => {
|
||||
child.parent = menu;
|
||||
setParent(child);
|
||||
});
|
||||
};
|
||||
menus.forEach(menu => setParent(menu));
|
||||
this._menus = menus;
|
||||
|
||||
let menuItemTag = menu => {
|
||||
let tag = this._menuItem
|
||||
.replace(/{menuID}/gi, menu.id)
|
||||
.replace(/{menuName}/gi, menu.name)
|
||||
.replace(/{url}/gi, !menu.url ? "javascript:void(0);" : wctx.url(menu.url));
|
||||
let parent = menu.children && menu.children.length > 0;
|
||||
tag = tag.replace(/{toggle}/gi, !parent ? "" : " menu-toggle");
|
||||
if (!parent)
|
||||
return tag.replace(/{menuSub}/gi, "");
|
||||
|
||||
let children = menu.children.map(child => menuItemTag(child)).join("\n\t")
|
||||
return tag.replace(/{menuSub}/gi, this._menuSub.replace(/{children}/gi, children));
|
||||
}
|
||||
let tags = (menus || []).map(menu => menuItemTag(menu));
|
||||
document.querySelector("#menus").innerHTML = tags.join("");
|
||||
|
||||
return this._init();
|
||||
}
|
||||
|
||||
_init() {
|
||||
document.querySelectorAll(this._selector).forEach(element => {
|
||||
let menu = new Menu(element, {
|
||||
orientation: this._orientation,
|
||||
closeChildren: this._horizontal,
|
||||
showDropdownOnHover: localStorage.getItem('templateCustomizer-' + this._template + '--ShowDropdownOnHover')
|
||||
? localStorage.getItem('templateCustomizer-' + this._template + '--ShowDropdownOnHover') === 'true'
|
||||
: window.templateCustomizer !== undefined
|
||||
? window.templateCustomizer.settings.defaultShowDropdownOnHover
|
||||
: true
|
||||
});
|
||||
|
||||
window.Helpers.scrollToActive(false); //animate = false
|
||||
window.Helpers.mainMenu = menu;
|
||||
});
|
||||
//Sets toggler
|
||||
document.querySelectorAll('.layout-menu-toggle').forEach(item => {
|
||||
item.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
window.Helpers.toggleCollapsed();
|
||||
if (config.enableMenuLocalStorage && !window.Helpers.isSmallScreen()) {
|
||||
try {
|
||||
localStorage.setItem(
|
||||
'templateCustomizer-' + this._template + '--LayoutCollapsed',
|
||||
String(window.Helpers.isCollapsed())
|
||||
);
|
||||
} catch (e) {}
|
||||
}
|
||||
});
|
||||
});
|
||||
// Display menu toggle (layout-menu-toggle) on hover with delay
|
||||
let delay = (elem, callback) => {
|
||||
let timeout = null;
|
||||
elem.onmouseenter = () => {
|
||||
// Set timeout to be a timer which will invoke callback after 300ms (not for small screen)
|
||||
timeout = !Helpers.isSmallScreen() ? setTimeout(callback, 300) : setTimeout(callback, 0);
|
||||
};
|
||||
|
||||
elem.onmouseleave = () => {
|
||||
// Clear any timers set to timeout
|
||||
document.querySelector('.layout-menu-toggle').classList.remove('d-block');
|
||||
clearTimeout(timeout);
|
||||
};
|
||||
};
|
||||
if (this._container) {
|
||||
delay(this._container, () => {
|
||||
// not for small screen
|
||||
if (!Helpers.isSmallScreen()) {
|
||||
document.querySelector('.layout-menu-toggle').classList.add('d-block');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**지정한 url의 메뉴를 활성화 한다.
|
||||
* @param url {string} 메뉴 url
|
||||
* @returns MenuSupport
|
||||
*/
|
||||
setActive(url) {
|
||||
document
|
||||
.querySelectorAll(this._selector + " li")
|
||||
.forEach(li => li.classList.remove("active", "open"));
|
||||
|
||||
let a = document.querySelector(this._selector + ' a[href=\"' + wctx.url(url) + '\"]');
|
||||
if (!a) return this;
|
||||
|
||||
let activate = (e, open) => {
|
||||
let p = e.parentNode;
|
||||
let tag = (p != this._container ? p : null) ? p.tagName : "";
|
||||
if (!tag) return;
|
||||
|
||||
if ("li" == tag.toLowerCase()) {
|
||||
p.classList.add("active");
|
||||
if (open)
|
||||
p.classList.add("open");
|
||||
}
|
||||
activate(p, true);
|
||||
|
||||
};
|
||||
|
||||
activate(a);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**지정하는 url의 메뉴 정보를 반환한다.
|
||||
* @param url {string} 메뉴 url
|
||||
* @returns 지정하는 url의 메뉴 정보
|
||||
*/
|
||||
getMenu(url) {
|
||||
let find = menus => {
|
||||
for (let i = 0; i < menus.length; ++i) {
|
||||
let menu = menus[i];
|
||||
if (url == menu.url)
|
||||
return menu;
|
||||
let found = find(menu.children || []);
|
||||
if (found)
|
||||
return found;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
return find(this._menus);
|
||||
}
|
||||
|
||||
breadcrumb(url, separator = " / ") {
|
||||
let menu = this.getMenu(url);
|
||||
if (!menu)
|
||||
return "";
|
||||
|
||||
let getName = menu => {
|
||||
let name = menu.name;
|
||||
let parent = !menu.parent ? "" : getName(menu.parent);
|
||||
return parent ? parent + separator + name : name;
|
||||
}
|
||||
|
||||
return getName(menu);
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
class MenuControl extends DatasetControl {
|
||||
constructor() {
|
||||
super({
|
||||
keymapper: info => info ? info.id : "",
|
||||
prefix:"menu",
|
||||
prefixName:"메뉴"
|
||||
});
|
||||
|
||||
this.urls.load = this.url("/tree.do");
|
||||
delete this.urls.getInfo;
|
||||
this.menus = [];
|
||||
}
|
||||
|
||||
setData(obj) {
|
||||
let list = [];
|
||||
let asList = array => {
|
||||
if (!array || array.length < 1) return;
|
||||
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
let menu = array[i];
|
||||
list.push(menu);
|
||||
asList(menu.children);
|
||||
}
|
||||
};
|
||||
asList(this.menus = Array.isArray(obj) ? obj : obj.menus);
|
||||
super.setData(list);
|
||||
}
|
||||
|
||||
move(parentID, menuID) {
|
||||
json.post({
|
||||
url:wctx.url("/menu/move.do"),
|
||||
data:{
|
||||
parentID:parentID,
|
||||
menuIDs:menuID
|
||||
},
|
||||
success:resp => {
|
||||
this._load();
|
||||
this.onMenusChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
reorder(menuIDs) {
|
||||
json.post({
|
||||
url:wctx.url("/menu/reorder.do"),
|
||||
data:{
|
||||
menuIDs:Array.isArray(menuIDs) ? menuIDs.join(",") : menuIDs
|
||||
},
|
||||
success:resp => {
|
||||
this._load();
|
||||
this.onMenusChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onSave(resp) {
|
||||
super.onSave(resp);
|
||||
this.onMenusChanged();
|
||||
}
|
||||
|
||||
onRemove(selected, resp) {
|
||||
super.onRemove(selected, resp);
|
||||
this.onMenusChanged();
|
||||
}
|
||||
|
||||
onMenusChanged() {}
|
||||
|
||||
async getUserMenus() {
|
||||
return new Promise((resolve, reject) => {
|
||||
json.get({
|
||||
url:this.url("/userMenus.do"),
|
||||
data:{},
|
||||
success:resp => resolve(resp.userMenus)
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
class UserControl extends DatasetControl {
|
||||
constructor(conf) {
|
||||
super(conf || {
|
||||
prefix:"user",
|
||||
prefixName:"사용자",
|
||||
infoSize:"xl",
|
||||
keymapper:info => info ? info.USER_ID : "",
|
||||
dataGetter:obj => obj.userList,
|
||||
formats: {
|
||||
REG_DT:datetimeFormat
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async selectUser(multiple) {
|
||||
return new Promise((resolve, reject) => {
|
||||
ajax.get({
|
||||
url:this.url("/select.do"),
|
||||
data:{multiple:multiple},
|
||||
success:resp => {
|
||||
dialog.open({
|
||||
title:"사용자 선택",
|
||||
content:resp,
|
||||
getData:() => {return getSelectedUser();},
|
||||
onOK:(selected) => resolve(selected)
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue