Skip to content

Commit e973713

Browse files
Class properties edit, add, remove; classes add, remove
1 parent c04020a commit e973713

File tree

9 files changed

+252
-42
lines changed

9 files changed

+252
-42
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "cache-visual-editor",
33
"printableName": "Cache Visual Editor",
4-
"version": "0.4.9",
4+
"version": "0.4.11",
55
"description": "Visual class editor for InterSystems Caché",
66
"main": "index.js",
77
"keywords": [

source/cache/VisualEditor.REST.Editor.cls

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,27 +28,58 @@ ClassMethod Save() As %Status
2828
set response = ##class(%ZEN.proxyObject).%New()
2929
set response.error = ""
3030
set response.modified = 0
31+
32+
#define nextClass set className = $order(classes(className)) continue
33+
3134
set className = $order(classes(""))
3235
while (className '= "") {
3336

37+
set classData = classes(className)
38+
39+
if ($data(classData.%data("$add"))) {
40+
set classDef = ##class(%Dictionary.ClassDefinition).%New()
41+
set classDef.Name = className
42+
} else {
43+
set classDef = ##class(%Dictionary.ClassDefinition).%OpenId(className)
44+
}
45+
if (classDef = "") {
46+
set response.error = response.error _ "Class " _ className _ " does not exists." _ $Char(10)
47+
$$$nextClass
48+
}
49+
50+
if ($data(classData.%data("$delete"))) {
51+
set error = $System.Status.GetErrorText(classDef.%Delete(classDef.%Oid()))
52+
if (error '= "") { set response.error = response.error _ error _ $CHAR(10) }
53+
set response.modified = response.modified + 1
54+
$$$nextClass
55+
}
56+
3457
set errorLog = ""
3558
set changes = 0
3659

3760
set properties = ""
38-
if ($ClassName(classes(className).Properties) = "%ZEN.proxyObject") {
61+
if ($ClassName(classData.Properties) = "%ZEN.proxyObject") {
3962
do classes(className).Properties.%CopyToArray(.properties)
4063
}
64+
65+
#define nextProperty set propertyName = $order(properties(propertyName)) continue
66+
4167
set propertyName = $order(properties(""))
4268
while (propertyName '= "") {
43-
set pDef = ##class(%Dictionary.PropertyDefinition).%OpenId(className_"||"_propertyName)
69+
set props = properties(propertyName)
70+
71+
if ($data(props.%data("$add"))) {
72+
set pDef = ##class(%Dictionary.PropertyDefinition).%New()
73+
set pDef.parent = classDef
74+
} else {
75+
set pDef = ##class(%Dictionary.PropertyDefinition).%OpenId(className_"||"_propertyName)
76+
}
4477
if (pDef = "") {
4578
set errorLog = errorLog _ "Property " _ propertyName _ " not found in "
4679
_ className _ $Char(10)
47-
set propertyName = $order(properties(propertyName))
48-
continue
80+
$$$nextProperty
4981
}
5082

51-
set props = properties(propertyName)
5283
set deleted = 0
5384
if ($data(props.%data("$delete"))) {
5485
set error = $System.Status.GetErrorText(pDef.%Delete(pDef.%Oid()))
@@ -71,27 +102,24 @@ ClassMethod Save() As %Status
71102
set changes = changes + 1
72103
}
73104

74-
set propertyName = $order(properties(propertyName))
105+
$$$nextProperty
75106
}
76107

77108
if (errorLog '= "") {
78109
set response.error = response.error _ errorLog
79-
set className = $order(classes(className))
80-
continue
110+
$$$nextClass
81111
}
82112

83113
set st = $system.OBJ.Compile(className, "cuk-d", .errorLog)
84114

85115
if (errorLog '= 0) {
86116
set response.error = response.error _ errorLog(1) _ $CHAR(10)
87-
set className = $order(classes(className))
88-
continue
117+
$$$nextClass
89118
}
90119

91120
set response.modified = response.modified + changes
92121

93-
set className = $order(classes(className))
94-
122+
$$$nextClass
95123
}
96124

97125
do response.%ToJSON(, "o")

source/client/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
<div class="page" id="classBuilder">
1818
<div class="header">
1919
<div class="panel">
20-
<div class="medium save icon" id="saveIndicator"></div>
20+
<div class="interactive medium add icon" id="addClass"></div>
21+
<div class="interactive medium save icon" id="saveIndicator"></div>
2122
<div class="interactive medium menu icon"></div>
2223
<div class="interactive medium back icon" id="backButton"></div>
2324
<span class="title">
Lines changed: 78 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import { loadLevel } from "./index";
2-
import { block } from "../domUtils";
1+
import { loadLevel, updateGrid } from "./index";
2+
import { block, getDummyForm, detach } from "../domUtils";
33
import { enableItem } from "./card/item";
4+
import { addChange } from "./changes";
5+
import { Toast } from "../toast/index";
46

57
function getPropertyBlock (classData, classBlockName, classBlockPropName) {
6-
let prop = classData[classBlockName][classBlockPropName],
8+
let div = block(`div`, `item`),
9+
prop = classData[classBlockName][classBlockPropName],
710
item = block(`div`, `header`),
811
iconBlock = block(`div`, `icons`),
912
icon = block(`div`, `icon ${ prop["Private"] ? "private" : "public" }`),
@@ -24,7 +27,37 @@ function getPropertyBlock (classData, classBlockName, classBlockPropName) {
2427
}
2528
item.appendChild(text);
2629
enableItem({headerElement: item, classData, classBlockName, classBlockPropName});
27-
return item;
30+
div.appendChild(item);
31+
return div;
32+
}
33+
34+
function getControls (body, classData, classBlockName) {
35+
let controls = block(`div`, `controls`),
36+
add = block(`div`, `interactive normal icon add`),
37+
nameInput = block(`input`);
38+
nameInput.type = "text";
39+
controls.appendChild(add);
40+
add.addEventListener(`click`, () => {
41+
let form = getDummyForm();
42+
nameInput.style.width = "0";
43+
nameInput.value = "TestProperty";
44+
form.appendChild(nameInput);
45+
setTimeout(() => nameInput.style.width = "150px", 1);
46+
controls.removeChild(add);
47+
controls.appendChild(form);
48+
form.addEventListener(`submit`, () => {
49+
let newProp = nameInput.value,
50+
path = [classData[`Name`], classBlockName, newProp];
51+
addChange(path.concat(`$add`), true);
52+
addChange(path.concat(`Name`), newProp);
53+
classData[classBlockName][newProp] = { Name: newProp };
54+
body.appendChild(getPropertyBlock(classData, classBlockName, newProp));
55+
detach(form);
56+
controls.appendChild(add);
57+
});
58+
});
59+
60+
return controls;
2861
}
2962

3063
/**
@@ -35,19 +68,20 @@ function getPropertyBlock (classData, classBlockName, classBlockPropName) {
3568
*/
3669
function getBlock (classBlockName, classData) {
3770

38-
let section = block(`div`, `section`), body, header;
71+
let section = block(`div`, `section`), body;
72+
//for (let classBlockPropName in classData[classBlockName]) {
73+
let header = block(`div`, `header`),
74+
span = block(`span`, `title`);
75+
body = block(`div`, `body`);
76+
header.appendChild(getControls(body, classData, classBlockName));
77+
header.appendChild(span);
78+
span.textContent = classBlockName;
79+
section.appendChild(header);
80+
section.appendChild(body);
81+
//break;
82+
//}
3983
for (let classBlockPropName in classData[classBlockName]) {
40-
header = block(`div`, `header`);
41-
header.textContent = classBlockName;
42-
body = block(`div`, `body`);
43-
section.appendChild(header);
44-
section.appendChild(body);
45-
break;
46-
}
47-
for (let classBlockPropName in classData[classBlockName]) {
48-
let div = block(`div`, `item`);
49-
div.appendChild(getPropertyBlock(classData, classBlockName, classBlockPropName));
50-
body.appendChild(div);
84+
body.appendChild(getPropertyBlock(classData, classBlockName, classBlockPropName));
5185
}
5286
return section;
5387

@@ -59,30 +93,48 @@ function getBlock (classBlockName, classData) {
5993
* @returns {HTMLElement}
6094
*/
6195
export function getCardElement (data) {
62-
let card = block(`div`, `card ${ data["_type"] }`),
96+
let type = data["_type"],
97+
card = block(`div`, `card ${ type }`),
6398
head = block(`div`, `head`),
99+
controls = block(`div`, `controls`),
100+
del = block(`div`, `interactive medium icon delete`),
64101
headIcon = block(`div`, `cardIcon ${ data["ClassType"] || "" }`),
65102
header = block(`div`, `header`);
66103

67104
header.textContent = data["name"];
105+
controls.appendChild(del);
106+
if (type === "class")
107+
head.appendChild(controls);
68108
head.appendChild(headIcon);
69109
head.appendChild(header);
70110
card.appendChild(head);
71-
//enableItem(head, data);
72111

73-
card.appendChild(getBlock("Parameters", data));
74-
card.appendChild(getBlock("Properties", data));
75-
card.appendChild(getBlock("Indices", data));
76-
card.appendChild(getBlock("Methods", data));
77-
card.appendChild(getBlock("Queries", data));
78-
card.appendChild(getBlock("XDatas", data));
79-
80-
if (data["_type"] === "package") {
112+
if (type === "class") {
113+
card.appendChild(getBlock("Parameters", data));
114+
card.appendChild(getBlock("Properties", data));
115+
card.appendChild(getBlock("Indices", data));
116+
card.appendChild(getBlock("Methods", data));
117+
card.appendChild(getBlock("Queries", data));
118+
card.appendChild(getBlock("XDatas", data));
119+
} else if (type === "package") {
81120
card.addEventListener("click", () => {
82121
loadLevel(data["fullName"]);
83122
});
84123
return card;
85124
}
86125

126+
let lastTimeDelClicked = 0;
127+
del.addEventListener(`click`, e => e.stopPropagation());
128+
del.addEventListener(`click`, () => {
129+
let delta = (-lastTimeDelClicked + (lastTimeDelClicked = (new Date()).getTime()));
130+
if (delta > 5000) { // > 5 sec - show message "click again to delete"
131+
new Toast(Toast.TYPE_INFO, `Click again to delete`);
132+
} else { // delete
133+
addChange([data["Name"]].concat(`$delete`), true);
134+
detach(card);
135+
updateGrid();
136+
}
137+
});
138+
87139
return card;
88140
}

source/client/js/classEditor/index.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { AutoGrid } from "../autoGrid";
33
import { getCardElement } from "./card";
44
import { block } from "../domUtils";
55
import { saveChanges } from "./changes";
6+
import { Toast } from "../toast";
7+
import { addChange } from "./changes";
68

79
var PATH = "",
810
INITIALIZED = false,
@@ -55,9 +57,42 @@ let backButton = onInit(() => {
5557
saveButton.style.opacity = 0;
5658
saveButton.addEventListener("click", () => {
5759
saveChanges(NAMESPACE, (res) => {
58-
if (!res["error"]) saveButton.style.opacity = 0;
60+
if (!res["error"]) {
61+
saveButton.style.opacity = 0;
62+
new Toast(Toast.TYPE_DONE, `Saved!`);
63+
} else {
64+
new Toast(Toast.TYPE_ERROR, res["error"]);
65+
}
5966
});
6067
});
68+
}),
69+
addClass = onInit(() => {
70+
addClass = document.querySelector("#addClass");
71+
addClass.addEventListener(`click`, () => {
72+
let type = PATH ? "class" : "package",
73+
name = prompt(
74+
`Enter a ${ type } name`,
75+
`New ${ type }`
76+
),
77+
fullName = `${ PATH ? PATH + "." : "" }${ name }`;
78+
let setup = {
79+
_type: type,
80+
name: name,
81+
Name: fullName,
82+
Properties: {},
83+
Methods: {},
84+
Queries: {},
85+
Parameters: {},
86+
Indices: {}
87+
};
88+
if (type === "class") {
89+
setup["ClassType"] = "registered";
90+
} else {
91+
setup["fullName"] = fullName;
92+
}
93+
grid.applyChild(getCardElement(setup));
94+
addChange([fullName, "$add"], true);
95+
});
6196
});
6297

6398
/**

source/client/js/domUtils.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ export function block (element = "div", className, textContent) {
1212
return el;
1313
}
1414

15+
export function getDummyForm () {
16+
let el = block(`form`);
17+
el.addEventListener(`submit`, e => e.preventDefault());
18+
return el;
19+
}
20+
1521
/**
1622
* Safely detach element from the DOM.
1723
* @param {HTMLElement} element

source/client/scss/basic.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ input[type=checkbox].toggle {
123123
float: right;
124124
}
125125

126+
#addClass {
127+
float: right;
128+
}
129+
126130
}
127131

128132
}

0 commit comments

Comments
 (0)