自動採番アクション追加・ドメイン追加
This commit is contained in:
File diff suppressed because one or more lines are too long
42
frontend/src/components/DomainSelector.vue
Normal file
42
frontend/src/components/DomainSelector.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<q-btn-dropdown
|
||||
color="primay"
|
||||
push
|
||||
flat
|
||||
no-caps
|
||||
icon="share"
|
||||
size="md"
|
||||
:label="`${userStore.currentDomain.domainName}.cybozu.com`"
|
||||
>
|
||||
<q-list>
|
||||
<q-item v-for="domain in domains" :key="domain.domainName"
|
||||
clickable v-close-popup @click="onItemClick(domain)">
|
||||
<q-item-section side>
|
||||
<q-icon name="share" size="sm" color="orange" text-color="white"></q-icon>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>{{ `${domain.domainName}.cybozu.com` }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-btn-dropdown>
|
||||
|
||||
</template>
|
||||
<script setup lang="ts" >
|
||||
import { IDomainInfo } from 'src/types/ActionTypes';
|
||||
import { useAuthStore,IUserState } from 'stores/useAuthStore';
|
||||
import { ref } from 'vue';
|
||||
const userStore = useAuthStore();
|
||||
const domains = ref<IDomainInfo[]>([]);
|
||||
(async ()=>{
|
||||
domains.value = await userStore.getUserDomains();
|
||||
})();
|
||||
|
||||
const onItemClick=(domain:IDomainInfo)=>{
|
||||
console.log(domain);
|
||||
userStore.setCurrentDomain(domain);
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
|
||||
<q-input v-model="selectedDate" :label="displayName" :placeholder="placeholder" mask="date" :rules="['date']">
|
||||
<q-input v-model="selectedDate" :label="displayName" :placeholder="placeholder" label-color="primary" mask="date" :rules="['date']" stack-label>
|
||||
<template v-slot:append>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||
@@ -29,6 +29,10 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
hint:{
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: '',
|
||||
|
||||
@@ -1,16 +1,29 @@
|
||||
<template>
|
||||
<q-input v-model="selectedField" :label="displayName" labelColor="" :placeholder="placeholder" clearable >
|
||||
<template v-slot:append>
|
||||
<q-field v-model="selectedField" :label="displayName" labelColor="primary"
|
||||
:clearable="isSelected" stack-label :bottom-slots="!isSelected" >
|
||||
<template v-slot:control >
|
||||
<q-chip color="primary" text-color="white" v-if="isSelected">
|
||||
{{ selectedField.name }}
|
||||
</q-chip>
|
||||
</template>
|
||||
<!-- <template v-slot:hint v-if="isSelected">
|
||||
<div> 項目コード:<q-chip size="sm" outline color="secondary" text-color="white">{{selectedField.code}}</q-chip></div>
|
||||
</template> -->
|
||||
<template v-slot:hint v-if="!isSelected">
|
||||
{{ placeholder }}
|
||||
</template>
|
||||
|
||||
<template v-slot:append>
|
||||
<q-icon name="search" class="cursor-pointer" @click="showDg"/>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</q-field>
|
||||
<show-dialog v-model:visible="show" name="フィールド一覧" @close="closeDg">
|
||||
<field-select ref="appDg" name="フィールド" type="single" :appId="store.appInfo?.appId"></field-select>
|
||||
</show-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref ,watchEffect} from 'vue';
|
||||
import { defineComponent, ref ,watchEffect,computed} from 'vue';
|
||||
import ShowDialog from '../ShowDialog.vue';
|
||||
import FieldSelect from '../FieldSelect.vue';
|
||||
import { useFlowEditorStore } from 'stores/flowEditor';
|
||||
@@ -29,10 +42,14 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
modelValue: {
|
||||
hint:{
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
modelValue: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
},
|
||||
|
||||
setup(props, { emit }) {
|
||||
@@ -40,6 +57,9 @@ export default defineComponent({
|
||||
const show = ref(false);
|
||||
const selectedField = ref(props.modelValue);
|
||||
const store = useFlowEditorStore();
|
||||
const isSelected = computed(()=>{
|
||||
return selectedField.value!==null && typeof selectedField.value === 'object' && ('name' in selectedField.value)
|
||||
});
|
||||
|
||||
const showDg = () => {
|
||||
show.value = true;
|
||||
@@ -47,7 +67,7 @@ export default defineComponent({
|
||||
|
||||
const closeDg = (val:string) => {
|
||||
if (val == 'OK') {
|
||||
selectedField.value = appDg.value.selected[0].code;
|
||||
selectedField.value = appDg.value.selected[0];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -62,6 +82,7 @@ export default defineComponent({
|
||||
showDg,
|
||||
closeDg,
|
||||
selectedField,
|
||||
isSelected
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<q-input :label="displayName" :placeholder="placeholder" v-model="inputValue"/>
|
||||
<q-input :label="displayName" v-model="inputValue" label-color="primary" :placeholder="placeholder" stack-label/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -16,13 +16,17 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
hint:{
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
|
||||
setup(props, { emit }) {
|
||||
setup(props , { emit }) {
|
||||
const inputValue = ref(props.modelValue);
|
||||
|
||||
watchEffect(() => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<q-input :label="displayName" :placeholder="placeholder" v-model="inputValue" autogrow />
|
||||
<q-input :label="displayName" label-color="primary" v-model="inputValue" :placeholder="placeholder" autogrow stack-label/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -16,6 +16,10 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
hint:{
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: '',
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
Kintone App Builder
|
||||
<q-badge align="top" outline>V{{ env.version }}</q-badge>
|
||||
</q-toolbar-title>
|
||||
<domain-selector></domain-selector>
|
||||
<q-btn flat round dense icon="logout" @click="authStore.logout()"/>
|
||||
</q-toolbar>
|
||||
|
||||
</q-header>
|
||||
|
||||
<q-drawer
|
||||
@@ -48,6 +48,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import EssentialLink, { EssentialLinkProps } from 'components/EssentialLink.vue';
|
||||
import DomainSelector from 'components/DomainSelector.vue';
|
||||
import { useAuthStore } from 'stores/useAuthStore';
|
||||
|
||||
const authStore = useAuthStore();
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { api } from 'boot/axios';
|
||||
import { Router } from '../router';
|
||||
import {IDomainInfo} from '../types/ActionTypes';
|
||||
|
||||
export interface IUserState{
|
||||
token?:string;
|
||||
returnUrl:string;
|
||||
currentDomain:IDomainInfo;
|
||||
}
|
||||
|
||||
export const useAuthStore = defineStore({
|
||||
id: 'auth',
|
||||
state: () => ({
|
||||
token: localStorage.getItem('token'),
|
||||
returnUrl: ''
|
||||
state: () :IUserState => ({
|
||||
token: localStorage.getItem('token')||'',
|
||||
returnUrl: '',
|
||||
currentDomain: JSON.parse(localStorage.getItem('currentDomain')||"{}")
|
||||
}),
|
||||
actions: {
|
||||
async login(username:string, password:string) {
|
||||
@@ -19,6 +26,8 @@ export const useAuthStore = defineStore({
|
||||
console.info(result);
|
||||
this.token =result.data.access_token;
|
||||
localStorage.setItem('token', result.data.access_token);
|
||||
this.currentDomain=await this.getCurrentDomain();
|
||||
localStorage.setItem('currentDomain',JSON.stringify(this.currentDomain));
|
||||
Router.push(this.returnUrl || '/');
|
||||
return true;
|
||||
}catch(e)
|
||||
@@ -27,10 +36,33 @@ export const useAuthStore = defineStore({
|
||||
return false;
|
||||
}
|
||||
},
|
||||
async getCurrentDomain():Promise<IDomainInfo>{
|
||||
return {
|
||||
domainName:'mfu07rkgnb7c',
|
||||
kintoneUrl:'https://mfu07rkgnb7c.cybozu.com'
|
||||
}
|
||||
},
|
||||
async getUserDomains():Promise<IDomainInfo[]>{
|
||||
return [
|
||||
{
|
||||
domainName:'mfu07rkgnb7c',
|
||||
kintoneUrl:'https://mfu07rkgnb7c.cybozu.com'
|
||||
},
|
||||
{
|
||||
domainName:'alicorn',
|
||||
kintoneUrl:'https://alicorn.cybozu.com'
|
||||
}
|
||||
]
|
||||
},
|
||||
logout() {
|
||||
this.token = null;
|
||||
this.token = undefined;
|
||||
localStorage.removeItem('token');
|
||||
localStorage.removeItem('currentDomain');
|
||||
Router.push('/login');
|
||||
},
|
||||
setCurrentDomain(domain:IDomainInfo){
|
||||
this.currentDomain=domain;
|
||||
localStorage.setItem('currentDomain',JSON.stringify(this.currentDomain));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
export interface IDomainInfo{
|
||||
domainName:string;
|
||||
kintoneUrl:string;
|
||||
}
|
||||
|
||||
/**
|
||||
* アプリ情報
|
||||
*/
|
||||
@@ -20,6 +25,8 @@ export interface IActionProperty {
|
||||
//プロパティ表示名
|
||||
displayName: string;
|
||||
placeholder: string;
|
||||
//入力提示・説明
|
||||
hint:string;
|
||||
//プロパティ設定値
|
||||
modelValue: any;
|
||||
};
|
||||
@@ -71,12 +78,13 @@ class ActionProperty implements IActionProperty {
|
||||
// プロパティ表示名
|
||||
displayName: string;
|
||||
placeholder: string;
|
||||
hint:string;
|
||||
// プロパティ設定値
|
||||
modelValue: any;
|
||||
};
|
||||
|
||||
static defaultProperty(): IActionProperty {
|
||||
return new ActionProperty('InputText', 'displayName', '表示名', '表示を入力してください', '');
|
||||
return new ActionProperty('InputText', 'displayName', '表示名', '表示を入力してください', '','');
|
||||
};
|
||||
|
||||
constructor(
|
||||
@@ -84,6 +92,7 @@ class ActionProperty implements IActionProperty {
|
||||
name: string,
|
||||
displayName: string,
|
||||
placeholder: string,
|
||||
hint:string,
|
||||
modelValue: any
|
||||
) {
|
||||
this.component = component;
|
||||
@@ -91,6 +100,7 @@ class ActionProperty implements IActionProperty {
|
||||
name: name,
|
||||
displayName: displayName,
|
||||
placeholder: placeholder,
|
||||
hint:hint,
|
||||
modelValue: modelValue
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jquery": "^3.5.24",
|
||||
"@types/node": "^20.8.9",
|
||||
"sass": "^1.69.5",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.4.5"
|
||||
},
|
||||
|
||||
132
plugin/kintone-addins/src/actions/auto-numbering.ts
Normal file
132
plugin/kintone-addins/src/actions/auto-numbering.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
|
||||
import { actionAddins } from ".";
|
||||
import { IField, IAction,IActionResult, IActionNode, IActionProperty } from "../types/ActionTypes";
|
||||
import { Formatter } from "../util/format";
|
||||
|
||||
declare global {
|
||||
interface Window { $format: any; }
|
||||
}
|
||||
|
||||
|
||||
interface IAutoNumberingProps{
|
||||
//文書番号を格納する
|
||||
field:IField;
|
||||
format:string;
|
||||
prefix:string;
|
||||
suffix:string;
|
||||
|
||||
}
|
||||
|
||||
export class AutoNumbering implements IAction{
|
||||
name: string;
|
||||
actionProps: IActionProperty[];
|
||||
props:IAutoNumberingProps;
|
||||
constructor(){
|
||||
this.name="自動採番する";
|
||||
this.actionProps=[];
|
||||
this.register();
|
||||
this.props={
|
||||
field:{code:''},
|
||||
format:'',
|
||||
prefix:'',
|
||||
suffix:''
|
||||
}
|
||||
globalThis.window.$format=this.format;
|
||||
this.register();
|
||||
}
|
||||
|
||||
async process(actionNode:IActionNode,event:any):Promise<IActionResult> {
|
||||
let result={
|
||||
canNext:false,
|
||||
result:false
|
||||
};
|
||||
try{
|
||||
this.actionProps=actionNode.actionProps;
|
||||
if (!('field' in actionNode.ActionValue) && !('format' in actionNode.ActionValue)) {
|
||||
return result
|
||||
}
|
||||
this.props = actionNode.ActionValue as IAutoNumberingProps;
|
||||
const record = event.record;
|
||||
const docNum = await this.createNumber(this.props);
|
||||
record[this.props.field.code].value=docNum;
|
||||
result= {
|
||||
canNext:true,
|
||||
result:true
|
||||
}
|
||||
return result;
|
||||
}catch(error){
|
||||
console.error(error);
|
||||
event.error="処理中異常が発生しました。";
|
||||
return {
|
||||
canNext:false,
|
||||
result:false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
execTemplate(template:string):string{
|
||||
if(template===undefined) return '';
|
||||
const regex = /\$\{([^}]+)\}/g;
|
||||
return template.replace(regex,(match,expr)=>{
|
||||
return this.execEval(match,expr);
|
||||
});
|
||||
}
|
||||
|
||||
execEval(match:string,expr:string):string{
|
||||
console.log(match);
|
||||
return eval(expr);
|
||||
}
|
||||
|
||||
format(pattern:string):string{
|
||||
const now=new Date();
|
||||
return Formatter.dateFormat(now, pattern);
|
||||
}
|
||||
|
||||
async createNumber(props:IAutoNumberingProps){
|
||||
let number :string='';
|
||||
let prefix:string='';
|
||||
let suffix:string='';
|
||||
|
||||
let no = await this.fetchNo();
|
||||
if(props.format!==undefined && props.format!==''){
|
||||
number=Formatter.numberFormat(no, props.format);
|
||||
}else{
|
||||
number=no.toString(10);
|
||||
}
|
||||
|
||||
if(props.prefix!==undefined && props.prefix!==''){
|
||||
prefix=this.execTemplate(props.prefix);
|
||||
}
|
||||
|
||||
if(props.suffix!==undefined && props.suffix!==''){
|
||||
suffix=this.execTemplate(props.suffix);
|
||||
}
|
||||
return `${prefix}${number}${suffix}`;
|
||||
}
|
||||
|
||||
async fetchNo():Promise<number>{
|
||||
let recNo=1;
|
||||
return await new kintone.Promise<number>((resolve,reject)=>{
|
||||
const appurl = kintone.api.url('/k/v1/records',true);
|
||||
const params={
|
||||
app:kintone.app.getId(),
|
||||
fields:['$id'],
|
||||
query:'limit 1'
|
||||
};
|
||||
return kintone.api(appurl,'GET',params).then((resp)=>{
|
||||
if(resp.records[0]!==null){
|
||||
recNo = parseInt(resp.records[0].$id.value,10)+1;
|
||||
}
|
||||
resolve(recNo);
|
||||
}).catch((error)=>{
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
register(): void {
|
||||
actionAddins[this.name]=this;
|
||||
}
|
||||
|
||||
}
|
||||
new AutoNumbering();
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
import { actionAddins } from ".";
|
||||
import { IAction,IActionResult, IActionNode, IActionProperty } from "../types/ActionTypes";
|
||||
import { IAction,IActionResult, IActionNode, IActionProperty, IField } from "../types/ActionTypes";
|
||||
|
||||
interface IMustInputProps{
|
||||
field:string;
|
||||
field:IField;
|
||||
message:string;
|
||||
}
|
||||
|
||||
@@ -16,13 +16,13 @@ export class MustInputAction implements IAction{
|
||||
this.actionProps=[];
|
||||
this.register();
|
||||
this.props={
|
||||
field:'',
|
||||
field:{code:''},
|
||||
message:''
|
||||
}
|
||||
this.register();
|
||||
}
|
||||
|
||||
process(actionNode:IActionNode,event:any):IActionResult {
|
||||
async process(actionNode:IActionNode,event:any):Promise<IActionResult> {
|
||||
let result={
|
||||
canNext:true,
|
||||
result:false
|
||||
@@ -33,9 +33,9 @@ export class MustInputAction implements IAction{
|
||||
}
|
||||
this.props = actionNode.ActionValue as IMustInputProps;
|
||||
const record = event.record;
|
||||
const value = record[this.props.field]?.value;
|
||||
const value = record[this.props.field.code]?.value;
|
||||
if(value===undefined || value===''){
|
||||
record[this.props.field].error=this.props.message;
|
||||
record[this.props.field.code].error=this.props.message;
|
||||
return result;
|
||||
}
|
||||
result= {
|
||||
|
||||
@@ -15,12 +15,12 @@ declare const alcflow : {
|
||||
|
||||
$(function (){
|
||||
const events=Object.keys(alcflow);
|
||||
kintone.events.on(events,(event:any)=>{
|
||||
kintone.events.on(events,async (event:any)=>{
|
||||
const flowinfo = alcflow[event.type];
|
||||
const flow=ActionFlow.fromJSON(flowinfo.content);
|
||||
if(flow!==undefined){
|
||||
const process = new ActionProcess(event.type,flow,event);
|
||||
process.exec();
|
||||
await process.exec();
|
||||
}
|
||||
return event;
|
||||
});
|
||||
|
||||
@@ -64,10 +64,16 @@ export interface IActionResult{
|
||||
export interface IAction{
|
||||
name:string;
|
||||
actionProps: Array<IActionProperty>;
|
||||
process(prop:IActionNode,event:any):IActionResult;
|
||||
process(prop:IActionNode,event:any):Promise<IActionResult>;
|
||||
register():void;
|
||||
}
|
||||
|
||||
export interface IField{
|
||||
name?:string;
|
||||
code:string;
|
||||
type?:string;
|
||||
}
|
||||
|
||||
/**
|
||||
* アクションのプロパティ定義に基づいたクラス
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
import { actionAddins } from "../actions";
|
||||
import '../actions/must-input';
|
||||
import '../actions/auto-numbering';
|
||||
import { ActionFlow,IActionFlow, IActionResult } from "./ActionTypes";
|
||||
|
||||
export class ActionProcess{
|
||||
@@ -12,7 +13,7 @@ export class ActionProcess{
|
||||
this.flow=flow;
|
||||
this.event=event;
|
||||
}
|
||||
exec(){
|
||||
async exec(){
|
||||
const root = this.flow.getRoot();
|
||||
if(root===undefined || root.nextNodeIds.size===0){
|
||||
return;
|
||||
@@ -26,7 +27,7 @@ export class ActionProcess{
|
||||
while(nextAction!==undefined && result.canNext){
|
||||
const action = actionAddins[nextAction.name];
|
||||
if(action!==undefined){
|
||||
result = action.process(nextAction,this.event)
|
||||
result = await action.process(nextAction,this.event)
|
||||
}
|
||||
const nextInput = nextAction.outputPoints!==undefined?result.result||'':'';
|
||||
id=nextAction.nextNodeIds.get(nextInput);
|
||||
|
||||
71
plugin/kintone-addins/src/util/format.ts
Normal file
71
plugin/kintone-addins/src/util/format.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
export class Formatter{
|
||||
static numberFormat(num:number,format:string):string{
|
||||
let integerPart = Math.floor(Math.abs(num)).toString();
|
||||
let fractionPart = Math.abs(num).toString().split('.')[1] || '';
|
||||
let isNegative = num < 0;
|
||||
let isPercent = format.includes('%');
|
||||
// %
|
||||
if (isPercent) {
|
||||
num *= 100;
|
||||
integerPart = Math.floor(Math.abs(num)).toString();
|
||||
fractionPart = Math.abs(num).toString().split('.')[1] || '';
|
||||
}
|
||||
|
||||
// 小数と整数部分の処理
|
||||
let [integerFormat, fractionFormat] = format.split('.');
|
||||
integerPart = integerFormat ? integerPart.padStart(integerFormat.replace(/[^0]/g, '').length, '0') : integerPart;
|
||||
fractionPart = fractionPart.padEnd(fractionFormat ? fractionFormat.length : 0, '0');
|
||||
|
||||
// カマ区切
|
||||
if (/,/.test(integerFormat)) {
|
||||
const parts = [];
|
||||
while (integerPart.length) {
|
||||
parts.unshift(integerPart.slice(-3));
|
||||
integerPart = integerPart.slice(0, -3);
|
||||
}
|
||||
integerPart = parts.join(',');
|
||||
}
|
||||
|
||||
// すべて組合わせ
|
||||
let result = fractionFormat ? `${integerPart}.${fractionPart}` : integerPart;
|
||||
result = isNegative ? `-${result}` : result;
|
||||
return isPercent ? `${result}%` : result;
|
||||
}
|
||||
|
||||
static dateFormat(date: Date, format: string): string {
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth() + 1;
|
||||
const day = date.getDate();
|
||||
const hour = date.getHours();
|
||||
const minute = date.getMinutes();
|
||||
const second = date.getSeconds();
|
||||
const millisecond = date.getMilliseconds();
|
||||
const timeZoneOffset = -date.getTimezoneOffset() / 60;
|
||||
|
||||
const replacements = {
|
||||
'yyyy': year.toString(),
|
||||
'yy': year.toString().slice(-2),
|
||||
'MM': month.toString().padStart(2, '0'),
|
||||
'M': month.toString(),
|
||||
'dd': day.toString().padStart(2, '0'),
|
||||
'd': day.toString(),
|
||||
'HH': hour.toString().padStart(2, '0'),
|
||||
'H': hour.toString(),
|
||||
'hh': (hour > 12 ? hour - 12 : hour).toString().padStart(2, '0'),
|
||||
'h': (hour > 12 ? hour - 12 : hour).toString(),
|
||||
'mm': minute.toString().padStart(2, '0'),
|
||||
'm': minute.toString(),
|
||||
'ss': second.toString().padStart(2, '0'),
|
||||
's': second.toString(),
|
||||
'fff': millisecond.toString().padStart(3, '0'),
|
||||
'zzz': (timeZoneOffset >= 0 ? '+' : '-') + Math.abs(timeZoneOffset).toString().padStart(2, '0') + ':00'
|
||||
};
|
||||
|
||||
return format.replace(/yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|m|ss|s|fff|zzz/g, (match) => {
|
||||
return replacements[match as keyof typeof replacements] || match;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"target": "ESNext",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"lib": ["esnext", "dom"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"moduleResolution": "node",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
@@ -17,7 +17,8 @@
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ export default defineConfig({
|
||||
rollupOptions: {
|
||||
input: 'src/index.ts', // entry file
|
||||
output:{
|
||||
entryFileNames:'alc_runtime.js'
|
||||
entryFileNames:'alc_runtime.js',
|
||||
// assetFileNames:'alc_kintone_style.css'
|
||||
}
|
||||
},
|
||||
sourcemap:true
|
||||
|
||||
@@ -119,11 +119,53 @@
|
||||
dependencies:
|
||||
"@types/sizzle" "*"
|
||||
|
||||
"@types/node@^20.8.9":
|
||||
version "20.8.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.9.tgz#646390b4fab269abce59c308fc286dcd818a2b08"
|
||||
integrity sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==
|
||||
dependencies:
|
||||
undici-types "~5.26.4"
|
||||
|
||||
"@types/sizzle@*":
|
||||
version "2.3.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.5.tgz#d93dd29cdcd5801d90be968073b09a6b370780e4"
|
||||
integrity sha512-tAe4Q+OLFOA/AMD+0lq8ovp8t3ysxAOeaScnfNdZpUxaGl51ZMDEITxkvFl1STudQ58mz6gzVGl9VhMKhwRnZQ==
|
||||
|
||||
anymatch@~3.1.2:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
|
||||
integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
|
||||
dependencies:
|
||||
normalize-path "^3.0.0"
|
||||
picomatch "^2.0.4"
|
||||
|
||||
binary-extensions@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
||||
|
||||
braces@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
||||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
|
||||
"chokidar@>=3.0.0 <4.0.0":
|
||||
version "3.5.3"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
|
||||
dependencies:
|
||||
anymatch "~3.1.2"
|
||||
braces "~3.0.2"
|
||||
glob-parent "~5.1.2"
|
||||
is-binary-path "~2.1.0"
|
||||
is-glob "~4.0.1"
|
||||
normalize-path "~3.0.0"
|
||||
readdirp "~3.6.0"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
esbuild@^0.18.10:
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6"
|
||||
@@ -152,11 +194,54 @@ esbuild@^0.18.10:
|
||||
"@esbuild/win32-ia32" "0.18.20"
|
||||
"@esbuild/win32-x64" "0.18.20"
|
||||
|
||||
fill-range@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
fsevents@~2.3.2:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
|
||||
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
||||
|
||||
glob-parent@~5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
immutable@^4.0.0:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f"
|
||||
integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==
|
||||
|
||||
is-binary-path@~2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
|
||||
dependencies:
|
||||
binary-extensions "^2.0.0"
|
||||
|
||||
is-extglob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
||||
|
||||
is-glob@^4.0.1, is-glob@~4.0.1:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-number@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
||||
|
||||
jquery@^3.7.1:
|
||||
version "3.7.1"
|
||||
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.1.tgz#083ef98927c9a6a74d05a6af02806566d16274de"
|
||||
@@ -167,11 +252,21 @@ nanoid@^3.3.6:
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
|
||||
integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
|
||||
|
||||
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
||||
picocolors@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.2.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
||||
|
||||
postcss@^8.4.27:
|
||||
version "8.4.31"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d"
|
||||
@@ -181,6 +276,13 @@ postcss@^8.4.27:
|
||||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.2"
|
||||
|
||||
readdirp@~3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
||||
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
rollup@^3.27.1:
|
||||
version "3.29.4"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981"
|
||||
@@ -188,16 +290,37 @@ rollup@^3.27.1:
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
source-map-js@^1.0.2:
|
||||
sass@^1.69.5:
|
||||
version "1.69.5"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.5.tgz#23e18d1c757a35f2e52cc81871060b9ad653dfde"
|
||||
integrity sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
source-map-js ">=0.6.2 <2.0.0"
|
||||
|
||||
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
||||
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
|
||||
dependencies:
|
||||
is-number "^7.0.0"
|
||||
|
||||
typescript@^5.0.2:
|
||||
version "5.2.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78"
|
||||
integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==
|
||||
|
||||
undici-types@~5.26.4:
|
||||
version "5.26.5"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
|
||||
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
|
||||
|
||||
vite@^4.4.5:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.0.tgz#ec406295b4167ac3bc23e26f9c8ff559287cff26"
|
||||
|
||||
52
sample.json
52
sample.json
@@ -1,20 +1,38 @@
|
||||
[
|
||||
{
|
||||
"component": "FieldInput",
|
||||
"props": {
|
||||
"displayName": "フィールド",
|
||||
"modelValue": "",
|
||||
"name": "field",
|
||||
"placeholder": "必須項目を選択してください"
|
||||
}
|
||||
},
|
||||
{
|
||||
"component": "MuiltInputText",
|
||||
"props": {
|
||||
"displayName": "エラーメッセージ",
|
||||
"modelValue": "",
|
||||
"name": "message",
|
||||
"placeholder": "エラーメッセージを入力してください"
|
||||
}
|
||||
{
|
||||
"component": "FieldInput",
|
||||
"props": {
|
||||
"displayName": "採番項目",
|
||||
"modelValue": {},
|
||||
"name": "field",
|
||||
"placeholder": "採番項目を選択してください"
|
||||
}
|
||||
},
|
||||
{
|
||||
"component": "InputText",
|
||||
"props": {
|
||||
"displayName": "フォーマット",
|
||||
"modelValue": "",
|
||||
"name": "format",
|
||||
"placeholder": "数値書式文字列を指定します"
|
||||
}
|
||||
},
|
||||
{
|
||||
"component": "InputText",
|
||||
"props": {
|
||||
"displayName": "前につける文字列",
|
||||
"modelValue": "",
|
||||
"name": "prefix",
|
||||
"placeholder": "前につける文字列を入力してください"
|
||||
}
|
||||
},
|
||||
{
|
||||
"component": "InputText",
|
||||
"props": {
|
||||
"displayName": "後ろにつける文字列",
|
||||
"modelValue": "",
|
||||
"name": "suffix",
|
||||
"placeholder": "後ろにつける文字列を入力してください"
|
||||
}
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user