Conflicts解決
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -381,23 +381,49 @@ def uploadkintonefiles(file,c:config.KINTONE_ENV):
|
|||||||
headers={config.API_V1_AUTH_KEY:c.API_V1_AUTH_VALUE}
|
headers={config.API_V1_AUTH_KEY:c.API_V1_AUTH_VALUE}
|
||||||
data ={'name':'file','filename':os.path.basename(file)}
|
data ={'name':'file','filename':os.path.basename(file)}
|
||||||
url = f"{c.BASE_URL}/k/v1/file.json"
|
url = f"{c.BASE_URL}/k/v1/file.json"
|
||||||
r = httpx.post(url,headers=headers,data=data,files=upload_files)
|
r = httpx.post(url,headers=headers,data=data,files=upload_files)
|
||||||
|
#{"name":data['filename'],'fileKey':r['fileKey']}
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
def updateappjscss(app,uploads,c:config.KINTONE_ENV):
|
def updateappjscss(app,uploads,c:config.KINTONE_ENV):
|
||||||
dsjs = []
|
dsjs = []
|
||||||
dscss = []
|
dscss = []
|
||||||
|
#mobile側
|
||||||
|
mbjs = []
|
||||||
|
mbcss = []
|
||||||
|
customize = getappcustomize(app, c)
|
||||||
|
current_js = customize['desktop'].get('js', [])
|
||||||
|
current_css = customize['desktop'].get('css', [])
|
||||||
|
current_mobile_js = customize['mobile'].get('js', [])
|
||||||
|
current_mobile_css = customize['mobile'].get('css', [])
|
||||||
|
current_js = [item for item in current_js if not (item.get('type') == 'URL' and item.get('url', '').endswith('alc_runtime.js'))]
|
||||||
|
|
||||||
for upload in uploads:
|
for upload in uploads:
|
||||||
for key in upload:
|
for key in upload:
|
||||||
|
filename = os.path.basename(key)
|
||||||
if key.endswith('.js'):
|
if key.endswith('.js'):
|
||||||
if (key.endswith('alc_runtime.js') and config.DEPLOY_MODE == "DEV"):
|
existing_js = next((item for item in current_js if item['file']['name'] == filename), None)
|
||||||
dsjs.append({'type':'URL','url':config.DEPLOY_JS_URL})
|
if existing_js:
|
||||||
|
existing_js['file']['fileKey'] = upload[key]
|
||||||
else:
|
else:
|
||||||
dsjs.append({'type':'FILE','file':{'fileKey':upload[key]}})
|
if (key.endswith('alc_runtime.js') and config.DEPLOY_MODE == "DEV"):
|
||||||
|
dsjs.append({'type':'URL','url':config.DEPLOY_JS_URL})
|
||||||
|
else:
|
||||||
|
dsjs.append({'type':'FILE','file':{'fileKey':upload[key]}})
|
||||||
elif key.endswith('.css'):
|
elif key.endswith('.css'):
|
||||||
dscss.append({'type':'FILE','file':{'fileKey':upload[key]}})
|
existing_css = next((item for item in current_css if item['file']['name'] == key), None)
|
||||||
|
if existing_css:
|
||||||
|
existing_css['file']['fileKey'] = upload[key]
|
||||||
|
else:
|
||||||
|
dscss.append({'type': 'FILE', 'file': {'fileKey': upload[key]}})
|
||||||
|
#現在のJSとCSSがdsjsに追加する
|
||||||
|
dsjs.extend(current_js)
|
||||||
|
dscss.extend(current_css)
|
||||||
|
mbjs.extend(current_mobile_js)
|
||||||
|
mbcss.extend(current_mobile_css)
|
||||||
|
|
||||||
ds ={'js':dsjs,'css':dscss}
|
ds ={'js':dsjs,'css':dscss}
|
||||||
mb ={'js':[],'css':[]}
|
mb ={'js':mbjs,'css':mbcss}
|
||||||
data = {'app':app,'scope':'ALL','desktop':ds,'mobile':mb}
|
data = {'app':app,'scope':'ALL','desktop':ds,'mobile':mb}
|
||||||
headers={config.API_V1_AUTH_KEY:c.API_V1_AUTH_VALUE,"Content-Type": "application/json"}
|
headers={config.API_V1_AUTH_KEY:c.API_V1_AUTH_VALUE,"Content-Type": "application/json"}
|
||||||
url = f"{c.BASE_URL}{config.API_V1_STR}/preview/app/customize.json"
|
url = f"{c.BASE_URL}{config.API_V1_STR}/preview/app/customize.json"
|
||||||
@@ -405,6 +431,15 @@ def updateappjscss(app,uploads,c:config.KINTONE_ENV):
|
|||||||
r = httpx.put(url,headers=headers,data=json.dumps(data))
|
r = httpx.put(url,headers=headers,data=json.dumps(data))
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
|
#kintone カスタマイズ情報
|
||||||
|
def getappcustomize(app,c:config.KINTONE_ENV):
|
||||||
|
headers={config.API_V1_AUTH_KEY:c.API_V1_AUTH_VALUE}
|
||||||
|
url = f"{c.BASE_URL}{config.API_V1_STR}/app/customize.json"
|
||||||
|
params = {"app":app}
|
||||||
|
r = httpx.get(url,headers=headers,params=params)
|
||||||
|
return r.json()
|
||||||
|
|
||||||
|
|
||||||
def getTempPath(filename):
|
def getTempPath(filename):
|
||||||
scriptdir = Path(__file__).resolve().parent
|
scriptdir = Path(__file__).resolve().parent
|
||||||
rootdir = scriptdir.parent.parent.parent.parent
|
rootdir = scriptdir.parent.parent.parent.parent
|
||||||
@@ -727,6 +762,7 @@ async def createjstokintone(request:Request,app:str,env:config.KINTONE_ENV = Dep
|
|||||||
for file in files:
|
for file in files:
|
||||||
upload = uploadkintonefiles(file,env)
|
upload = uploadkintonefiles(file,env)
|
||||||
if upload.get('fileKey') != None:
|
if upload.get('fileKey') != None:
|
||||||
|
print(upload)
|
||||||
jscs.append({ file :upload['fileKey']})
|
jscs.append({ file :upload['fileKey']})
|
||||||
appjscs = updateappjscss(app,jscs,env)
|
appjscs = updateappjscss(app,jscs,env)
|
||||||
if appjscs.get("revision") != None:
|
if appjscs.get("revision") != None:
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ const onSaveActionProps=(props:IActionProperty[])=>{
|
|||||||
$q.notify({
|
$q.notify({
|
||||||
type: 'positive',
|
type: 'positive',
|
||||||
caption: "通知",
|
caption: "通知",
|
||||||
message: `${store.activeNode?.subTitle}の属性設定を更新しました。`
|
message: `${store.activeNode?.subTitle}の属性を設定しました。(保存はされていません)`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
86
plugin/kintone-addins/src/actions/date-specified.ts
Normal file
86
plugin/kintone-addins/src/actions/date-specified.ts
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import { actionAddins } from ".";
|
||||||
|
import { IAction, IActionResult, IActionNode, IActionProperty, IField ,IContext, IVarName} from "../types/ActionTypes";
|
||||||
|
/**
|
||||||
|
* アクションの属性定義
|
||||||
|
*/
|
||||||
|
interface IDateSpecifiedProps {
|
||||||
|
verNameGet:string;
|
||||||
|
newYear:number;
|
||||||
|
newMonth:number;
|
||||||
|
newDay:number;
|
||||||
|
verName:IVarName;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 日付指定アクション
|
||||||
|
*/
|
||||||
|
export class DateSpecifiedAction implements IAction {
|
||||||
|
name: string;
|
||||||
|
actionProps: IActionProperty[];
|
||||||
|
props: IDateSpecifiedProps;
|
||||||
|
constructor() {
|
||||||
|
this.name = "日付指定";
|
||||||
|
this.actionProps = [];
|
||||||
|
this.props = {
|
||||||
|
verNameGet:'',
|
||||||
|
newYear:0,
|
||||||
|
newMonth:0,
|
||||||
|
newDay:0,
|
||||||
|
verName:{name:''}
|
||||||
|
}
|
||||||
|
this.register();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* アクションの実行を呼び出す
|
||||||
|
* @param actionNode
|
||||||
|
* @param event
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async process(actionNode: IActionNode, event: any,context:IContext): Promise<IActionResult> {
|
||||||
|
let result = {
|
||||||
|
canNext: true,
|
||||||
|
result: false
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
//属性設定を取得する
|
||||||
|
this.actionProps = actionNode.actionProps;
|
||||||
|
if (!('verName' in actionNode.ActionValue) && !('verNameGet' in actionNode.ActionValue) ) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
this.props = actionNode.ActionValue as IDateSpecifiedProps;
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//本番コード開始:
|
||||||
|
//取得変数の値を呼び出して代入する:
|
||||||
|
const getContextVarByPath = (obj: any, path: string) => {
|
||||||
|
return path.split(".").reduce((o, k) => (o || {})[k], obj);
|
||||||
|
};
|
||||||
|
let verNameGetValue = getContextVarByPath(context.variables,this.props.verNameGet);
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//取得変数の値Dateオブジェクトに変換:
|
||||||
|
let dateObj = new Date(verNameGetValue);
|
||||||
|
// 年の設定(newYearが設定されていない場合は、元の値を使用)
|
||||||
|
dateObj.setFullYear(this.props.newYear >=1900 && this.props.newYear <=9999 ? this.props.newYear : dateObj.getFullYear());
|
||||||
|
// 月の設定(newMonthが設定されていない場合は、元の値を使用)// 月は0始まりなので、12月は11。
|
||||||
|
dateObj.setMonth(this.props.newMonth >=1 && this.props.newMonth <=12 ? this.props.newMonth-1 : dateObj.getMonth());
|
||||||
|
// 日の設定(newDayが設定されていない場合は、元の値を使用)
|
||||||
|
dateObj.setDate(this.props.newDay >=1 && this.props.newDay <=31 ?this.props.newDay : dateObj.getDate());
|
||||||
|
// 変数に新しい値を設定
|
||||||
|
if(this.props.verName && this.props.verName.name!==''){
|
||||||
|
context.variables[this.props.verName.name]=dateObj.toISOString();
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
result = {
|
||||||
|
canNext:true,
|
||||||
|
result:true
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}catch(error){
|
||||||
|
context.errors.handleError(error,actionNode);
|
||||||
|
result.canNext=false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
register(): void {
|
||||||
|
actionAddins[this.name] = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new DateSpecifiedAction();
|
||||||
202
plugin/kintone-addins/src/actions/datetime-calc.ts
Normal file
202
plugin/kintone-addins/src/actions/datetime-calc.ts
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
import { actionAddins } from ".";
|
||||||
|
import { IAction, IActionResult, IActionNode, IActionProperty, IField ,IContext, IVarName} from "../types/ActionTypes";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* アクションの属性定義
|
||||||
|
*/
|
||||||
|
interface IDateTimeCalcProps{
|
||||||
|
verName:IVarName;
|
||||||
|
calcOption:string;
|
||||||
|
resultVerName:string;
|
||||||
|
year:string;
|
||||||
|
month:string;
|
||||||
|
date:string;
|
||||||
|
hour:string;
|
||||||
|
minute:string;
|
||||||
|
second:string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export class DateTimeCalcAction implements IAction{
|
||||||
|
name: string;
|
||||||
|
actionProps: IActionProperty[];
|
||||||
|
props:IDateTimeCalcProps;
|
||||||
|
constructor(){
|
||||||
|
this.name="日時を加算/減算する";// DBに登録したアクション名
|
||||||
|
this.actionProps=[];
|
||||||
|
//プロパティ属性の初期化
|
||||||
|
this.props={
|
||||||
|
verName:{name:''},
|
||||||
|
calcOption:'',
|
||||||
|
resultVerName:'',
|
||||||
|
year:"0",
|
||||||
|
month:"0",
|
||||||
|
date:"0",
|
||||||
|
hour:"0",
|
||||||
|
minute:"0",
|
||||||
|
second:"0"
|
||||||
|
}
|
||||||
|
//アクションを登録する
|
||||||
|
this.register();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基準日となる変数の値が、日付・日時の形式であるか、判断する
|
||||||
|
* @param {string} dateValue
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isDateValue(dateValue :string){
|
||||||
|
let date;
|
||||||
|
|
||||||
|
//正規表現チェック
|
||||||
|
let singleDigitMonth = dateValue.match(/(\d{4})-(\d{1})-(\d{1})$/);//4桁の数字-1桁の数字-2桁の数字
|
||||||
|
let twoDigitMonth = dateValue.match(/(\d{4})-(\d{2})-(\d{2})$/);//4桁の数字-2桁の数字-2桁の数字
|
||||||
|
let singleDigitDate = dateValue.match(/(\d{4})-(\d{2})-(\d{1})$/);//4桁の数字-2桁の数字-1桁の数字
|
||||||
|
let twoDigitDate = dateValue.match(/(\d{4})-(\d{1})-(\d{2})$/);//4桁の数字-1桁の数字-2桁の数字
|
||||||
|
let dateTimeMilliSecond = dateValue.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}).(\d{2,3})Z$/);//時刻入りのUTCの日付形式(ミリ秒)
|
||||||
|
let dateTime = dateValue.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/);//時刻入りのUTCの日付形式
|
||||||
|
|
||||||
|
//date型に変換
|
||||||
|
date = new Date(dateValue);
|
||||||
|
|
||||||
|
//date型変換できたか確認
|
||||||
|
if(date !== undefined && !isNaN(date.getDate())){
|
||||||
|
//正規表現チェック確認
|
||||||
|
if(twoDigitMonth === null && singleDigitMonth === null && singleDigitDate === null && twoDigitDate === null && dateTime === null && dateTimeMilliSecond === null){
|
||||||
|
throw new Error("計算の基準日となる値が、適切な日付・日時の形式ではありません。「日時を加算/減算する」コンポーネントの処理を中断しました。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 値を数値に変換する
|
||||||
|
* @param {any} context
|
||||||
|
* @param {string} calcValue,calcOption
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
valueToNumber(context :any,calcValue :string,calcOption :string): number{
|
||||||
|
|
||||||
|
const getContextVarByPath = (obj: any, path: string) => {
|
||||||
|
return path.split(".").reduce((o, k) => (o || {})[k], obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
//計算値が変数の場合は、変数の値を取得
|
||||||
|
if(calcOption === "変数" && isNaN(Number(calcValue))){
|
||||||
|
calcValue = getContextVarByPath (context.variables,calcValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
//数値型に変換
|
||||||
|
let number = Number(calcValue);
|
||||||
|
|
||||||
|
//有限数かどうか判定
|
||||||
|
if(!isFinite(number)){
|
||||||
|
throw new Error("計算値が、数値ではありません。「日時を加算/減算する」コンポーネントの処理を中断しました。");
|
||||||
|
}
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日付・日時を加算・減算する
|
||||||
|
* @param {any} dateValue
|
||||||
|
* @param {number} year month day hour minute second
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
calcDate(dateValue:any,year:number,month:number,date:number,hour:number,minute:number,second:number):string{
|
||||||
|
|
||||||
|
let calcResult;
|
||||||
|
//フィールドの値(文字列)をdate型に変換する
|
||||||
|
dateValue = new Date(dateValue);
|
||||||
|
|
||||||
|
// 年を計算
|
||||||
|
dateValue.setFullYear(dateValue.getFullYear()+year);
|
||||||
|
//月を計算
|
||||||
|
dateValue.setMonth(dateValue.getMonth()+month);
|
||||||
|
//日を計算
|
||||||
|
dateValue.setDate(dateValue.getDate()+date);
|
||||||
|
//時間を計算
|
||||||
|
dateValue.setHours(dateValue.getHours()+hour);
|
||||||
|
//分を計算
|
||||||
|
dateValue.setMinutes(dateValue.getMinutes()+minute);
|
||||||
|
//秒を計算
|
||||||
|
dateValue.setSeconds(dateValue.getSeconds()+second);
|
||||||
|
|
||||||
|
//UTC形式に変換
|
||||||
|
calcResult = dateValue.toISOString();
|
||||||
|
return calcResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* アクションの実行を呼び出す
|
||||||
|
* @param actionNode
|
||||||
|
* @param event
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async process(actionNode:IActionNode,event:any,context:IContext):Promise<IActionResult> {
|
||||||
|
let result={
|
||||||
|
canNext:true,
|
||||||
|
result:false
|
||||||
|
};
|
||||||
|
try{
|
||||||
|
//属性設定を取得する
|
||||||
|
this.actionProps = actionNode.actionProps;
|
||||||
|
this.props = actionNode.ActionValue as IDateTimeCalcProps;
|
||||||
|
|
||||||
|
const getContextVarByPath = (obj: any, path: string) => {
|
||||||
|
return path.split(".").reduce((o, k) => (o || {})[k], obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
//基準日となる変数の値取得
|
||||||
|
const dateValue = getContextVarByPath (context.variables,this.props.verName.name);
|
||||||
|
|
||||||
|
//基準日となる変数の値が空の場合、処理を終了する
|
||||||
|
if(!dateValue){
|
||||||
|
throw new Error("基準値となる変数の値が空、または存在しません。「日時を加算/減算する」コンポーネントの処理を中断しました。");
|
||||||
|
}
|
||||||
|
|
||||||
|
let checkDateValue;
|
||||||
|
//基準値となる変数の値、日時、日付形式か確認する
|
||||||
|
checkDateValue = this.isDateValue(dateValue);
|
||||||
|
|
||||||
|
if(checkDateValue){
|
||||||
|
//計算値の入力方法を取得する
|
||||||
|
let calcOptions = this.props.calcOption;
|
||||||
|
|
||||||
|
//計算値を数値型に変換する
|
||||||
|
let year = this.valueToNumber(context,this.props.year,calcOptions);
|
||||||
|
let month = this.valueToNumber(context,this.props.month,calcOptions);
|
||||||
|
let date = this.valueToNumber(context,this.props.date,calcOptions);
|
||||||
|
let hour = this.valueToNumber(context,this.props.hour,calcOptions);
|
||||||
|
let minute = this.valueToNumber(context,this.props.minute,calcOptions);
|
||||||
|
let second = this.valueToNumber(context,this.props.second,calcOptions);
|
||||||
|
|
||||||
|
//計算結果の日付を格納する変数
|
||||||
|
let calculatedDate;
|
||||||
|
|
||||||
|
//日付を加算、減算する
|
||||||
|
calculatedDate = this.calcDate(dateValue,year,month,date,hour,minute,second);
|
||||||
|
|
||||||
|
//計算結果を変数に代入する
|
||||||
|
context.variables[this.props.resultVerName] = calculatedDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
result= {
|
||||||
|
canNext:true,
|
||||||
|
result:true
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}catch(error){
|
||||||
|
context.errors.handleError(error,actionNode);
|
||||||
|
result.canNext=false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
register(): void {
|
||||||
|
actionAddins[this.name]=this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new DateTimeCalcAction();
|
||||||
77
plugin/kintone-addins/src/actions/end-of-month.ts
Normal file
77
plugin/kintone-addins/src/actions/end-of-month.ts
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import { actionAddins } from ".";
|
||||||
|
import { IAction, IActionResult, IActionNode, IActionProperty, IField ,IContext, IVarName} from "../types/ActionTypes";
|
||||||
|
/**
|
||||||
|
* アクションの属性定義
|
||||||
|
*/
|
||||||
|
interface IEndOfMonthProps {
|
||||||
|
verNameGet:string;
|
||||||
|
verName:IVarName;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 月末算出アクション
|
||||||
|
*/
|
||||||
|
export class EndOfMonthAction implements IAction {
|
||||||
|
name: string;
|
||||||
|
actionProps: IActionProperty[];
|
||||||
|
props: IEndOfMonthProps;
|
||||||
|
constructor() {
|
||||||
|
this.name = "月末算出";
|
||||||
|
this.actionProps = [];
|
||||||
|
this.props = {
|
||||||
|
verNameGet:'',
|
||||||
|
verName:{name:''}
|
||||||
|
}
|
||||||
|
this.register();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* アクションの実行を呼び出す
|
||||||
|
* @param actionNode
|
||||||
|
* @param event
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async process(actionNode: IActionNode, event: any,context:IContext): Promise<IActionResult> {
|
||||||
|
let result = {
|
||||||
|
canNext: true,
|
||||||
|
result: false
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
//属性設定を取得する
|
||||||
|
this.actionProps = actionNode.actionProps;
|
||||||
|
if (!('verName' in actionNode.ActionValue) && !('verNameGet' in actionNode.ActionValue) ) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
this.props = actionNode.ActionValue as IEndOfMonthProps;
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//本番コード開始:
|
||||||
|
//取得変数の値を呼び出して代入する:
|
||||||
|
const getContextVarByPath = (obj: any, path: string) => {
|
||||||
|
return path.split(".").reduce((o, k) => (o || {})[k], obj);
|
||||||
|
};
|
||||||
|
let verNameGetValue = getContextVarByPath(context.variables,this.props.verNameGet);
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//取得変数の値Dateオブジェクトに変換:
|
||||||
|
let dateObj = new Date(verNameGetValue);
|
||||||
|
// 月末を計算
|
||||||
|
let year = dateObj.getFullYear();
|
||||||
|
let month = dateObj.getMonth() + 1; //月は0から始まるため、1を足す
|
||||||
|
let lastDayOfMonth = new Date(year, month, 0); // 翌月の0日目は今月の月末
|
||||||
|
if(this.props.verName && this.props.verName.name!==''){
|
||||||
|
context.variables[this.props.verName.name]=lastDayOfMonth.toISOString();
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
result = {
|
||||||
|
canNext:true,
|
||||||
|
result:true
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}catch(error){
|
||||||
|
context.errors.handleError(error,actionNode);
|
||||||
|
result.canNext=false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
register(): void {
|
||||||
|
actionAddins[this.name] = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new EndOfMonthAction();
|
||||||
202
plugin/kintone-addins/src/actions/style-field.ts
Normal file
202
plugin/kintone-addins/src/actions/style-field.ts
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
import { Record } from "@kintone/rest-api-client/lib/src/client/types";
|
||||||
|
import { actionAddins } from ".";
|
||||||
|
import { IAction,IActionResult, IActionNode, IActionProperty, IField, IContext } from "../types/ActionTypes";
|
||||||
|
import { ConditionTree } from '../types/Conditions';
|
||||||
|
|
||||||
|
type TextStyle = "太字" | "斜体" | "下線" | "打ち消し線";
|
||||||
|
type StyleRigion = "書式変更フィールド" | "行全体"|"";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* アクションの属性定義
|
||||||
|
*/
|
||||||
|
interface IStyleFieldProps{
|
||||||
|
field:IField;
|
||||||
|
fontColor:string;
|
||||||
|
bgColor:string;
|
||||||
|
fontStyle:TextStyle[];
|
||||||
|
allRow:StyleRigion;
|
||||||
|
condition:string;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 条件書式表示アクション
|
||||||
|
*/
|
||||||
|
export class StyleFieldAction implements IAction{
|
||||||
|
name: string;
|
||||||
|
actionProps: IActionProperty[];
|
||||||
|
props:IStyleFieldProps;
|
||||||
|
constructor(){
|
||||||
|
this.name="条件書式表示";
|
||||||
|
this.actionProps=[];
|
||||||
|
this.props={
|
||||||
|
field:{code:''},
|
||||||
|
fontColor:'',
|
||||||
|
bgColor:'',
|
||||||
|
fontStyle:[],
|
||||||
|
allRow:'',
|
||||||
|
condition:''
|
||||||
|
}
|
||||||
|
//アクションを登録する
|
||||||
|
this.register();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* アクションの実行を呼び出す
|
||||||
|
* @param actionNode
|
||||||
|
* @param event
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async process(actionNode:IActionNode,event:any,context:IContext):Promise<IActionResult> {
|
||||||
|
let result={
|
||||||
|
canNext:true,
|
||||||
|
result:false
|
||||||
|
};
|
||||||
|
try{
|
||||||
|
//属性設定を取得する
|
||||||
|
this.actionProps=actionNode.actionProps;
|
||||||
|
if (!('field' in actionNode.ActionValue) && !('allRow' in actionNode.ActionValue)) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
this.props = actionNode.ActionValue as IStyleFieldProps;
|
||||||
|
//書式設定
|
||||||
|
if(event.type==="app.record.index.show"){
|
||||||
|
this.setStyleForView(event,this.props,context);
|
||||||
|
}else if(event.type==="app.record.detail.show"){
|
||||||
|
this.setStyleForDetail(event,this.props,context);
|
||||||
|
}
|
||||||
|
result= {
|
||||||
|
canNext:true,
|
||||||
|
result:true
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}catch(error){
|
||||||
|
context.errors.handleError(error,actionNode);
|
||||||
|
result.canNext=false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 詳細表示時のスタイル設定
|
||||||
|
* @param event
|
||||||
|
* @param props
|
||||||
|
* @param context
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
setStyleForDetail(event:any,props:IStyleFieldProps,context:IContext){
|
||||||
|
const elem = kintone.app.record.getFieldElement(props.field.code);
|
||||||
|
if(!elem){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const tree = this.getCondition(props.condition);
|
||||||
|
const conditionResult = this.getConditionResult(tree,context);
|
||||||
|
if(conditionResult){
|
||||||
|
this.setFieldStyle(props,elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一覧表示時の書式設定
|
||||||
|
* @param event
|
||||||
|
* @param props
|
||||||
|
* @param context
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
setStyleForView(event:any,props:IStyleFieldProps,context:IContext){
|
||||||
|
const records:Record[] = event.records;
|
||||||
|
const cells = kintone.app.getFieldElements(props.field.code);
|
||||||
|
if(!cells){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let elem :HTMLElement|null;
|
||||||
|
const conditionTree = this.getCondition(props.condition);
|
||||||
|
records.forEach((record:Record,index:number) => {
|
||||||
|
const currContext:IContext = {
|
||||||
|
variables:context.variables,
|
||||||
|
record:record,
|
||||||
|
errors:context.errors
|
||||||
|
}
|
||||||
|
const conditionResult = this.getConditionResult(conditionTree,currContext);
|
||||||
|
if(conditionResult){
|
||||||
|
elem = cells[index];
|
||||||
|
if(props.allRow==="行全体"){
|
||||||
|
elem = cells[index].parentElement;
|
||||||
|
}
|
||||||
|
if(elem){
|
||||||
|
this.setFieldStyle(props,elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param props HtmlElement書式設定
|
||||||
|
*/
|
||||||
|
setFieldStyle(props:IStyleFieldProps,elem:HTMLElement){
|
||||||
|
|
||||||
|
if(props.fontColor){
|
||||||
|
elem.style.color=props.fontColor;
|
||||||
|
}
|
||||||
|
if(props.bgColor){
|
||||||
|
elem.style.backgroundColor=props.bgColor;
|
||||||
|
}
|
||||||
|
if(props.fontStyle.length>0){
|
||||||
|
if(props.fontStyle.includes("斜体")){
|
||||||
|
elem.style.fontStyle="italic";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(props.fontStyle.includes("太字")){
|
||||||
|
elem.style.fontWeight = "bold";
|
||||||
|
}
|
||||||
|
let textDecoration="";
|
||||||
|
if(props.fontStyle.includes("下線")){
|
||||||
|
textDecoration="underline";
|
||||||
|
}
|
||||||
|
if(props.fontStyle.includes("打ち消し線")){
|
||||||
|
textDecoration = textDecoration? textDecoration + " line-through":"line-through";
|
||||||
|
}
|
||||||
|
if(textDecoration){
|
||||||
|
elem.style.textDecoration=textDecoration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条件式を実行する
|
||||||
|
* @param tree 条件式オブジェクト
|
||||||
|
* @param context
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getConditionResult(tree:ConditionTree|null, context:any):boolean{
|
||||||
|
if(!tree){
|
||||||
|
//条件を設定されていません
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return tree.evaluate(tree.root,context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param condition 条件式ツリーを取得する
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getCondition(condition:string):ConditionTree|null{
|
||||||
|
try{
|
||||||
|
const tree = new ConditionTree();
|
||||||
|
tree.fromJson(condition);
|
||||||
|
if(tree.getConditions(tree.root).length>0){
|
||||||
|
return tree;
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}catch(error){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register(): void {
|
||||||
|
actionAddins[this.name]=this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new StyleFieldAction();
|
||||||
@@ -22,6 +22,10 @@ import '../actions/half-full-conversion';
|
|||||||
import '../actions/login-user-getter';
|
import '../actions/login-user-getter';
|
||||||
import '../actions/auto-lookup';
|
import '../actions/auto-lookup';
|
||||||
import '../actions/field-disable';
|
import '../actions/field-disable';
|
||||||
|
import '../actions/style-field';
|
||||||
|
import '../actions/datetime-calc';
|
||||||
|
import '../actions/end-of-month';
|
||||||
|
import '../actions/date-specified';
|
||||||
import '../actions/cascading-dropdown';
|
import '../actions/cascading-dropdown';
|
||||||
import { ActionFlow,ErrorManager,IActionFlow, IActionResult,IContext } from "./ActionTypes";
|
import { ActionFlow,ErrorManager,IActionFlow, IActionResult,IContext } from "./ActionTypes";
|
||||||
const ShowErrorEvents:string[] = [
|
const ShowErrorEvents:string[] = [
|
||||||
|
|||||||
Reference in New Issue
Block a user